Merge "Add Contact ID to StreamItem-Fields"
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 3cec66f..0dba18b 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -106,6 +106,7 @@
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/R/com/android/systemui/R.java)
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/media/java/android/media/IAudioService.P)
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/media/java/android/media/IAudioService.P)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/media/audio/)
# ************************************************
# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
# ************************************************
diff --git a/api/current.txt b/api/current.txt
index 886d7a3..01b07a6 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -184,21 +184,21 @@
public static final class R.attr {
ctor public R.attr();
field public static final int absListViewStyle = 16842858; // 0x101006a
- 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 accessibilityEventTypes = 16843643; // 0x101037b
+ field public static final int accessibilityFeedbackType = 16843645; // 0x101037d
+ field public static final int accessibilityFlags = 16843647; // 0x101037f
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 actionBarDivider = 16843685; // 0x10103a5
- field public static final int actionBarItemBackground = 16843686; // 0x10103a6
+ field public static final int actionBarDivider = 16843684; // 0x10103a4
+ field public static final int actionBarItemBackground = 16843685; // 0x10103a5
field public static final int actionBarSize = 16843499; // 0x10102eb
- field public static final int actionBarSplitStyle = 16843666; // 0x1010392
+ field public static final int actionBarSplitStyle = 16843665; // 0x1010391
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 = 16843681; // 0x10103a1
+ field public static final int actionBarWidgetTheme = 16843680; // 0x10103a0
field public static final int actionButtonStyle = 16843480; // 0x10102d8
field public static final int actionDropDownStyle = 16843479; // 0x10102d7
field public static final int actionLayout = 16843515; // 0x10102fb
@@ -210,11 +210,11 @@
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 = 16843642; // 0x101037a
- field public static final int actionModeSplitBackground = 16843687; // 0x10103a7
- field public static final int actionModeStyle = 16843678; // 0x101039e
+ field public static final int actionModeSelectAllDrawable = 16843641; // 0x1010379
+ field public static final int actionModeSplitBackground = 16843686; // 0x10103a6
+ field public static final int actionModeStyle = 16843677; // 0x101039d
field public static final int actionOverflowButtonStyle = 16843510; // 0x10102f6
- field public static final int actionProviderClass = 16843667; // 0x1010393
+ field public static final int actionProviderClass = 16843666; // 0x1010392
field public static final int actionViewClass = 16843516; // 0x10102fc
field public static final int activatedBackgroundIndicator = 16843517; // 0x10102fd
field public static final int activityCloseEnterAnimation = 16842938; // 0x10100ba
@@ -226,7 +226,7 @@
field public static final int alertDialogIcon = 16843605; // 0x1010355
field public static final int alertDialogStyle = 16842845; // 0x101005d
field public static final int alertDialogTheme = 16843529; // 0x1010309
- field public static final int alignmentMode = 16843638; // 0x1010376
+ field public static final int alignmentMode = 16843637; // 0x1010375
field public static final int allContactsName = 16843468; // 0x10102cc
field public static final int allowBackup = 16843392; // 0x1010280
field public static final int allowClearUserData = 16842757; // 0x1010005
@@ -260,8 +260,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 = 16843669; // 0x1010395
- field public static final int backgroundStacked = 16843668; // 0x1010394
+ field public static final int backgroundSplit = 16843668; // 0x1010394
+ field public static final int backgroundStacked = 16843667; // 0x1010393
field public static final int backupAgent = 16843391; // 0x101027f
field public static final int baseline = 16843548; // 0x101031c
field public static final int baselineAlignBottom = 16843042; // 0x1010122
@@ -270,7 +270,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 = 16843655; // 0x1010387
+ field public static final int bottomChevronDrawable = 16843654; // 0x1010386
field public static final int bottomDark = 16842953; // 0x10100c9
field public static final int bottomLeftRadius = 16843179; // 0x10101ab
field public static final int bottomMedium = 16842958; // 0x10100ce
@@ -289,7 +289,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 = 16843649; // 0x1010381
+ field public static final int canRetrieveWindowContent = 16843648; // 0x1010380
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
@@ -318,18 +318,18 @@
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 = 16843674; // 0x101039a
+ field public static final int colorActivatedHighlight = 16843673; // 0x1010399
field public static final int colorBackground = 16842801; // 0x1010031
field public static final int colorBackgroundCacheHint = 16843435; // 0x10102ab
- field public static final int colorFocusedHighlight = 16843673; // 0x1010399
+ field public static final int colorFocusedHighlight = 16843672; // 0x1010398
field public static final int colorForeground = 16842800; // 0x1010030
field public static final int colorForegroundInverse = 16843270; // 0x1010206
- 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 colorLongPressedHighlight = 16843671; // 0x1010397
+ field public static final int colorMultiSelectHighlight = 16843674; // 0x101039a
+ field public static final int colorPressedHighlight = 16843670; // 0x1010396
+ field public static final int columnCount = 16843634; // 0x1010372
field public static final int columnDelay = 16843215; // 0x10101cf
- field public static final int columnOrderPreserved = 16843636; // 0x1010374
+ field public static final int columnOrderPreserved = 16843635; // 0x1010373
field public static final int columnWidth = 16843031; // 0x1010117
field public static final int compatibleWidthLimitDp = 16843621; // 0x1010365
field public static final int completionHint = 16843122; // 0x1010172
@@ -383,11 +383,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 = 16843677; // 0x101039d
+ field public static final int drawableEnd = 16843676; // 0x101039c
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 = 16843676; // 0x101039c
+ field public static final int drawableStart = 16843675; // 0x101039b
field public static final int drawableTop = 16843117; // 0x101016d
field public static final int drawingCacheQuality = 16842984; // 0x10100e8
field public static final int dropDownAnchor = 16843363; // 0x1010263
@@ -444,7 +444,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 = 16843661; // 0x101038d
+ field public static final int feedbackCount = 16843660; // 0x101038c
field public static final int fillAfter = 16843197; // 0x10101bd
field public static final int fillBefore = 16843196; // 0x10101bc
field public static final int fillEnabled = 16843343; // 0x101024f
@@ -497,7 +497,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 = 16843651; // 0x1010383
+ field public static final int handleDrawable = 16843650; // 0x1010382
field public static final int handleProfiling = 16842786; // 0x1010022
field public static final int hapticFeedbackEnabled = 16843358; // 0x101025e
field public static final int hardwareAccelerated = 16843475; // 0x10102d3
@@ -506,12 +506,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 = 16843658; // 0x101038a
+ field public static final int hitRadius = 16843657; // 0x1010389
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 = 16843663; // 0x101038f
+ field public static final int horizontalOffset = 16843662; // 0x101038e
field public static final int horizontalScrollViewStyle = 16843603; // 0x1010353
field public static final int horizontalSpacing = 16843028; // 0x1010114
field public static final int host = 16842792; // 0x1010028
@@ -557,7 +557,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 = 16843643; // 0x101037b
+ field public static final int isAuxiliary = 16843642; // 0x101037a
field public static final int isDefault = 16843297; // 0x1010221
field public static final int isIndicator = 16843079; // 0x1010147
field public static final int isModifier = 16843334; // 0x1010246
@@ -610,7 +610,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 int layout_columnSpan = 16843641; // 0x1010379
+ field public static final int layout_columnSpan = 16843640; // 0x1010378
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
@@ -618,8 +618,8 @@
field public static final int layout_marginLeft = 16842999; // 0x10100f7
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 int layout_rowSpan = 16843640; // 0x1010378
+ field public static final int layout_row = 16843638; // 0x1010376
+ field public static final int layout_rowSpan = 16843639; // 0x1010377
field public static final int layout_scale = 16843155; // 0x1010193
field public static final int layout_span = 16843085; // 0x101014d
field public static final int layout_toLeftOf = 16843138; // 0x1010182
@@ -629,7 +629,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 = 16843652; // 0x1010384
+ field public static final int leftChevronDrawable = 16843651; // 0x1010383
field public static final int lineSpacingExtra = 16843287; // 0x1010217
field public static final int lineSpacingMultiplier = 16843288; // 0x1010218
field public static final int lines = 16843092; // 0x1010154
@@ -641,8 +641,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 = 16843664; // 0x1010390
- field public static final int listPreferredItemHeightSmall = 16843665; // 0x1010391
+ field public static final int listPreferredItemHeightLarge = 16843663; // 0x101038f
+ field public static final int listPreferredItemHeightSmall = 16843664; // 0x1010390
field public static final int listSelector = 16843003; // 0x10100fb
field public static final int listSeparatorTextViewStyle = 16843272; // 0x1010208
field public static final int listViewStyle = 16842868; // 0x1010074
@@ -673,8 +673,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 = 16843680; // 0x10103a0
- field public static final int minResizeWidth = 16843679; // 0x101039f
+ field public static final int minResizeHeight = 16843679; // 0x101039f
+ field public static final int minResizeWidth = 16843678; // 0x101039e
field public static final int minSdkVersion = 16843276; // 0x101020c
field public static final int minWidth = 16843071; // 0x101013f
field public static final int mode = 16843134; // 0x101017e
@@ -690,7 +690,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 = 16843647; // 0x101037f
+ field public static final int notificationTimeout = 16843646; // 0x101037e
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
@@ -704,11 +704,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 = 16843657; // 0x1010389
+ field public static final int outerRadius = 16843656; // 0x1010388
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 = 16843645; // 0x101037d
+ field public static final int packageNames = 16843644; // 0x101037c
field public static final int padding = 16842965; // 0x10100d5
field public static final int paddingBottom = 16842969; // 0x10100d9
field public static final int paddingLeft = 16842966; // 0x10100d6
@@ -793,17 +793,17 @@
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 = 16843653; // 0x1010385
+ field public static final int rightChevronDrawable = 16843652; // 0x1010384
field public static final int ringtonePreferenceStyle = 16842899; // 0x1010093
field public static final int ringtoneType = 16843257; // 0x10101f9
field public static final int rotation = 16843558; // 0x1010326
field public static final int rotationX = 16843559; // 0x1010327
field public static final int rotationY = 16843560; // 0x1010328
- field public static final int rowCount = 16843633; // 0x1010371
+ field public static final int rowCount = 16843632; // 0x1010370
field public static final int rowDelay = 16843216; // 0x10101d0
field public static final int rowEdgeFlags = 16843329; // 0x1010241
field public static final int rowHeight = 16843058; // 0x1010132
- field public static final int rowOrderPreserved = 16843634; // 0x1010372
+ field public static final int rowOrderPreserved = 16843633; // 0x1010371
field public static final int saveEnabled = 16842983; // 0x10100e7
field public static final int scaleGravity = 16843262; // 0x10101fe
field public static final int scaleHeight = 16843261; // 0x10101fd
@@ -869,7 +869,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 = 16843660; // 0x101038c
+ field public static final int snapMargin = 16843659; // 0x101038b
field public static final int soundEffectsEnabled = 16843285; // 0x1010215
field public static final int spacing = 16843027; // 0x1010113
field public static final int spinnerDropDownItemStyle = 16842887; // 0x1010087
@@ -915,11 +915,10 @@
field public static final int stretchMode = 16843030; // 0x1010116
field public static final int subtitle = 16843473; // 0x10102d1
field public static final int subtitleTextStyle = 16843513; // 0x10102f9
- field public static final int subtypeExtraValue = 16843684; // 0x10103a4
- field public static final int subtypeLocale = 16843683; // 0x10103a3
+ field public static final int subtypeExtraValue = 16843683; // 0x10103a3
+ field public static final int subtypeLocale = 16843682; // 0x10103a2
field public static final int suggestActionMsg = 16843228; // 0x10101dc
field public static final int suggestActionMsgColumn = 16843229; // 0x10101dd
- field public static final int suggestionsEnabled = 16843632; // 0x1010370
field public static final int summary = 16843241; // 0x10101e9
field public static final int summaryColumn = 16843426; // 0x10102a2
field public static final int summaryOff = 16843248; // 0x10101f0
@@ -936,7 +935,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 = 16843650; // 0x1010382
+ field public static final int targetDrawables = 16843649; // 0x1010381
field public static final int targetPackage = 16842785; // 0x1010021
field public static final int targetSdkVersion = 16843376; // 0x1010270
field public static final int taskAffinity = 16842770; // 0x1010012
@@ -951,15 +950,15 @@
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 = 16843670; // 0x1010396
+ field public static final int textAllCaps = 16843669; // 0x1010395
field public static final int textAppearance = 16842804; // 0x1010034
field public static final int textAppearanceButton = 16843271; // 0x1010207
field public static final int textAppearanceInverse = 16842805; // 0x1010035
field public static final int textAppearanceLarge = 16842816; // 0x1010040
field public static final int textAppearanceLargeInverse = 16842819; // 0x1010043
field public static final int textAppearanceLargePopupMenu = 16843521; // 0x1010301
- field public static final int textAppearanceListItem = 16843688; // 0x10103a8
- field public static final int textAppearanceListItemSmall = 16843689; // 0x10103a9
+ field public static final int textAppearanceListItem = 16843687; // 0x10103a7
+ field public static final int textAppearanceListItemSmall = 16843688; // 0x10103a8
field public static final int textAppearanceMedium = 16842817; // 0x1010041
field public static final int textAppearanceMediumInverse = 16842820; // 0x1010044
field public static final int textAppearanceSearchResultSubtitle = 16843424; // 0x10102a0
@@ -1027,7 +1026,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 = 16843654; // 0x1010386
+ field public static final int topChevronDrawable = 16843653; // 0x1010385
field public static final int topDark = 16842951; // 0x10100c7
field public static final int topLeftRadius = 16843177; // 0x10101a9
field public static final int topOffset = 16843352; // 0x1010258
@@ -1039,12 +1038,12 @@
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 uiOptions = 16843681; // 0x10103a1
field public static final int uncertainGestureColor = 16843382; // 0x1010276
field public static final int unfocusedMonthDateColor = 16843588; // 0x1010344
field public static final int unselectedAlpha = 16843278; // 0x101020e
field public static final int updatePeriodMillis = 16843344; // 0x1010250
- field public static final int useDefaultMargins = 16843637; // 0x1010375
+ field public static final int useDefaultMargins = 16843636; // 0x1010374
field public static final int useIntrinsicSizeAsMinimum = 16843536; // 0x1010310
field public static final int useLevel = 16843167; // 0x101019f
field public static final int userVisible = 16843409; // 0x1010291
@@ -1058,10 +1057,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 = 16843662; // 0x101038e
+ field public static final int verticalOffset = 16843661; // 0x101038d
field public static final int verticalScrollbarPosition = 16843572; // 0x1010334
field public static final int verticalSpacing = 16843029; // 0x1010115
- field public static final int vibrationDuration = 16843659; // 0x101038b
+ field public static final int vibrationDuration = 16843658; // 0x101038a
field public static final int visibility = 16842972; // 0x10100dc
field public static final int visible = 16843156; // 0x1010194
field public static final int vmSafeMode = 16843448; // 0x10102b8
@@ -1078,7 +1077,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 = 16843656; // 0x1010388
+ field public static final int waveDrawable = 16843655; // 0x1010387
field public static final int webTextViewStyle = 16843449; // 0x10102b9
field public static final int webViewStyle = 16842885; // 0x1010085
field public static final int weekDayTextAppearance = 16843592; // 0x1010348
@@ -8721,7 +8720,6 @@
public class SurfaceTexture {
ctor public SurfaceTexture(int);
- ctor public SurfaceTexture(int, boolean);
method public long getTimestamp();
method public void getTransformMatrix(float[]);
method public void release();
@@ -11691,6 +11689,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);
method public static void incrementOperationCount(int, int);
method public static void setThreadStatsTag(int);
method public static deprecated void setThreadStatsTag(java.lang.String);
@@ -13975,6 +13974,7 @@
}
public final class GLUtils {
+ method public static java.lang.String getEGLErrorString(int);
method public static int getInternalFormat(android.graphics.Bitmap);
method public static int getType(android.graphics.Bitmap);
method public static void texImage2D(int, int, int, android.graphics.Bitmap, int);
@@ -15459,6 +15459,7 @@
field public static final java.lang.String AUTHORITY = "com.android.calendar";
field public static final java.lang.String CALLER_IS_SYNCADAPTER = "caller_is_syncadapter";
field public static final android.net.Uri CONTENT_URI;
+ field public static final java.lang.String EXTRA_EVENT_ALL_DAY = "allDay";
field public static final java.lang.String EXTRA_EVENT_BEGIN_TIME = "beginTime";
field public static final java.lang.String EXTRA_EVENT_END_TIME = "endTime";
}
@@ -17145,14 +17146,14 @@
field public static final java.lang.String SETTINGS_CLASSNAME = "settings_classname";
field public static final java.lang.String SYS_PROP_SETTING_VERSION = "sys.settings_secure_version";
field public static final java.lang.String TOUCH_EXPLORATION_ENABLED = "touch_exploration_enabled";
- field public static final java.lang.String TTS_DEFAULT_COUNTRY = "tts_default_country";
- field public static final java.lang.String TTS_DEFAULT_LANG = "tts_default_lang";
+ field public static final deprecated java.lang.String TTS_DEFAULT_COUNTRY = "tts_default_country";
+ field public static final deprecated java.lang.String TTS_DEFAULT_LANG = "tts_default_lang";
field public static final java.lang.String TTS_DEFAULT_PITCH = "tts_default_pitch";
field public static final java.lang.String TTS_DEFAULT_RATE = "tts_default_rate";
field public static final java.lang.String TTS_DEFAULT_SYNTH = "tts_default_synth";
- field public static final java.lang.String TTS_DEFAULT_VARIANT = "tts_default_variant";
+ field public static final deprecated java.lang.String TTS_DEFAULT_VARIANT = "tts_default_variant";
field public static final java.lang.String TTS_ENABLED_PLUGINS = "tts_enabled_plugins";
- field public static final java.lang.String TTS_USE_DEFAULTS = "tts_use_defaults";
+ field public static final deprecated java.lang.String TTS_USE_DEFAULTS = "tts_use_defaults";
field public static final java.lang.String USB_MASS_STORAGE_ENABLED = "usb_mass_storage_enabled";
field public static final java.lang.String USE_GOOGLE_MAIL = "use_google_mail";
field public static final java.lang.String WIFI_MAX_DHCP_RETRY_COUNT = "wifi_max_dhcp_retry_count";
@@ -20812,6 +20813,7 @@
method public java.lang.String getLocale();
method public int getSpanTypeId();
method public java.lang.String[] getSuggestions();
+ method public void setFlags(int);
method public void updateDrawState(android.text.TextPaint);
method public void writeToParcel(android.os.Parcel, int);
field public static final java.lang.String ACTION_SUGGESTION_PICKED = "android.text.style.SUGGESTION_PICKED";
@@ -27132,7 +27134,6 @@
method public void setSingleLine();
method public void setSingleLine(boolean);
method public final void setSpannableFactory(android.text.Spannable.Factory);
- method public void setSuggestionsEnabled(boolean);
method public final void setText(java.lang.CharSequence);
method public void setText(java.lang.CharSequence, android.widget.TextView.BufferType);
method public final void setText(char[], int, int);
diff --git a/cmds/dumpstate/dumpstate.c b/cmds/dumpstate/dumpstate.c
index 836cf15..0b08c5e 100644
--- a/cmds/dumpstate/dumpstate.c
+++ b/cmds/dumpstate/dumpstate.c
@@ -80,6 +80,9 @@
dump_file("SLAB INFO", "/proc/slabinfo");
dump_file("ZONEINFO", "/proc/zoneinfo");
dump_file("PAGETYPEINFO", "/proc/pagetypeinfo");
+ dump_file("BUDDYINFO", "/proc/buddyinfo");
+ dump_file("QTAGUID CTRL INFO", "/proc/net/xt_qtaguid/ctrl");
+ run_command("QTAGUID STATS INFO", 10, "su", "root", "cat", "/proc/net/xt_qtaguid/stats", NULL);
if (screenshot_path[0]) {
LOGI("taking screenshot\n");
@@ -114,8 +117,10 @@
dump_file("NETWORK ROUTES", "/proc/net/route");
dump_file("NETWORK ROUTES IPV6", "/proc/net/ipv6_route");
dump_file("ARP CACHE", "/proc/net/arp");
- run_command("IPTABLES", 10, "su", "root", "iptables", "-L", "-n", NULL);
+ run_command("IPTABLES", 10, "su", "root", "iptables", "-L", "-nvx", NULL);
+ run_command("IP6TABLES", 10, "su", "root", "ip6tables", "-L", "-nvx", NULL);
run_command("IPTABLE NAT", 10, "su", "root", "iptables", "-t", "nat", "-L", "-n", NULL);
+ run_command("IPT6ABLE NAT", 10, "su", "root", "ip6tables", "-t", "nat", "-L", "-n", NULL);
run_command("WIFI NETWORKS", 20,
"su", "root", "wpa_cli", "list_networks", NULL);
diff --git a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
index 8b4e7aee..7c41082 100644
--- a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
+++ b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
@@ -18,6 +18,7 @@
import android.accessibilityservice.AccessibilityServiceInfo;
import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.IAccessibilityInteractionConnectionCallback;
/**
* Interface given to an AccessibilitySerivce to talk to the AccessibilityManagerService.
@@ -30,84 +31,79 @@
/**
* Finds an {@link AccessibilityNodeInfo} by accessibility id.
- * <p>
- * <strong>
- * It is a client responsibility to recycle the received info by
- * calling {@link AccessibilityNodeInfo#recycle()} to avoid creating
- * of multiple instances.
- * </strong>
- * </p>
*
* @param accessibilityWindowId A unique window id.
* @param accessibilityViewId A unique View accessibility id.
- * @return The node info.
+ * @param interactionId The id of the interaction for matching with the callback result.
+ * @param callback Callback which to receive the result.
+ * @param threadId The id of the calling thread.
+ * @return The current window scale, where zero means a failure.
*/
- AccessibilityNodeInfo findAccessibilityNodeInfoByAccessibilityId(int accessibilityWindowId,
- int accessibilityViewId);
+ float findAccessibilityNodeInfoByAccessibilityId(int accessibilityWindowId,
+ int accessibilityViewId, int interactionId,
+ IAccessibilityInteractionConnectionCallback callback, long threadId);
/**
* Finds {@link AccessibilityNodeInfo}s by View text. The match is case
* insensitive containment. The search is performed in the window whose
* id is specified and starts from the View whose accessibility id is
* specified.
- * <p>
- * <strong>
- * It is a client responsibility to recycle the received infos by
- * calling {@link AccessibilityNodeInfo#recycle()} to avoid creating
- * of multiple instances.
- * </strong>
- * </p>
*
* @param text The searched text.
- * @param accessibilityId The id of the view from which to start searching.
+ * @param accessibilityWindowId A unique window id.
+ * @param accessibilityViewId A unique View accessibility id from where to start the search.
* Use {@link android.view.View#NO_ID} to start from the root.
- * @return A list of node info.
+ * @param interactionId The id of the interaction for matching with the callback result.
+ * @param callback Callback which to receive the result.
+ * @param threadId The id of the calling thread.
+ * @return The current window scale, where zero means a failure.
*/
- List<AccessibilityNodeInfo> findAccessibilityNodeInfosByViewText(String text,
- int accessibilityWindowId, int accessibilityViewId);
+ float findAccessibilityNodeInfosByViewText(String text, int accessibilityWindowId,
+ int accessibilityViewId, int interractionId,
+ IAccessibilityInteractionConnectionCallback callback, long threadId);
/**
* Finds {@link AccessibilityNodeInfo}s by View text. The match is case
* insensitive containment. The search is performed in the currently
* active window and start from the root View in the window.
- * <p>
- * <strong>
- * It is a client responsibility to recycle the received infos by
- * calling {@link AccessibilityNodeInfo#recycle()} to avoid creating
- * of multiple instances.
- * </strong>
- * </p>
*
* @param text The searched text.
* @param accessibilityId The id of the view from which to start searching.
* Use {@link android.view.View#NO_ID} to start from the root.
- * @return A list of node info.
+ * @param interactionId The id of the interaction for matching with the callback result.
+ * @param callback Callback which to receive the result.
+ * @param threadId The id of the calling thread.
+ * @return The current window scale, where zero means a failure.
*/
- List<AccessibilityNodeInfo> findAccessibilityNodeInfosByViewTextInActiveWindow(String text);
+ float findAccessibilityNodeInfosByViewTextInActiveWindow(String text,
+ int interactionId, IAccessibilityInteractionConnectionCallback callback,
+ long threadId);
/**
* Finds an {@link AccessibilityNodeInfo} by View id. The search is performed
- * in the currently active window and start from the root View in the window.
- * <p>
- * <strong>
- * It is a client responsibility to recycle the received info by
- * calling {@link AccessibilityNodeInfo#recycle()} to avoid creating
- * of multiple instances.
- * </strong>
- * </p>
+ * in the currently active window and starts from the root View in the window.
*
* @param id The id of the node.
- * @return The node info.
+ * @param interactionId The id of the interaction for matching with the callback result.
+ * @param callback Callback which to receive the result.
+ * @param threadId The id of the calling thread.
+ * @return The current window scale, where zero means a failure.
*/
- AccessibilityNodeInfo findAccessibilityNodeInfoByViewIdInActiveWindow(int viewId);
+ float findAccessibilityNodeInfoByViewIdInActiveWindow(int viewId, int interactionId,
+ IAccessibilityInteractionConnectionCallback callback, long threadId);
/**
* Performs an accessibility action on an {@link AccessibilityNodeInfo}.
*
* @param accessibilityWindowId The id of the window.
- * @param accessibilityViewId The of a view in the .
+ * @param accessibilityViewId A unique View accessibility id.
+ * @param action The action to perform.
+ * @param interactionId The id of the interaction for matching with the callback result.
+ * @param callback Callback which to receive the result.
+ * @param threadId The id of the calling thread.
* @return Whether the action was performed.
*/
boolean performAccessibilityAction(int accessibilityWindowId, int accessibilityViewId,
- int action);
+ int action, int interactionId, IAccessibilityInteractionConnectionCallback callback,
+ long threadId);
}
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 93e30af..102fac1 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -235,6 +235,24 @@
}
/**
+ * Use to decide whether the running device can be considered a "large
+ * RAM" device. Exactly what memory limit large RAM is will vary, but
+ * it essentially means there is plenty of RAM to have lots of background
+ * processes running under decent loads.
+ * @hide
+ */
+ static public boolean isLargeRAM() {
+ MemInfoReader reader = new MemInfoReader();
+ reader.readMemInfo();
+ if (reader.getTotalSize() >= (640*1024*1024)) {
+ // Currently 640MB RAM available to the kernel is the point at
+ // which we have plenty of RAM to spare.
+ return true;
+ }
+ return false;
+ }
+
+ /**
* Information you can retrieve about tasks that the user has most recently
* started or visited.
*/
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index ff04757..f81ea81 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -107,19 +107,22 @@
private final int mHeight;
private int mDrawLeft;
private int mDrawTop;
+ private final Paint mPaint;
private FastBitmapDrawable(Bitmap bitmap) {
mBitmap = bitmap;
mWidth = bitmap.getWidth();
mHeight = bitmap.getHeight();
+
setBounds(0, 0, mWidth, mHeight);
+
+ mPaint = new Paint();
+ mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));
}
@Override
public void draw(Canvas canvas) {
- Paint paint = new Paint();
- paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));
- canvas.drawBitmap(mBitmap, mDrawLeft, mDrawTop, paint);
+ canvas.drawBitmap(mBitmap, mDrawLeft, mDrawTop, mPaint);
}
@Override
@@ -134,33 +137,23 @@
}
@Override
- public void setBounds(Rect bounds) {
- // TODO Auto-generated method stub
- super.setBounds(bounds);
- }
-
- @Override
public void setAlpha(int alpha) {
- throw new UnsupportedOperationException(
- "Not supported with this drawable");
+ throw new UnsupportedOperationException("Not supported with this drawable");
}
@Override
public void setColorFilter(ColorFilter cf) {
- throw new UnsupportedOperationException(
- "Not supported with this drawable");
+ throw new UnsupportedOperationException("Not supported with this drawable");
}
@Override
public void setDither(boolean dither) {
- throw new UnsupportedOperationException(
- "Not supported with this drawable");
+ throw new UnsupportedOperationException("Not supported with this drawable");
}
@Override
public void setFilterBitmap(boolean filter) {
- throw new UnsupportedOperationException(
- "Not supported with this drawable");
+ throw new UnsupportedOperationException("Not supported with this drawable");
}
@Override
@@ -230,7 +223,7 @@
}
mWallpaper = null;
try {
- mWallpaper = getCurrentWallpaperLocked(context);
+ mWallpaper = getCurrentWallpaperLocked();
} catch (OutOfMemoryError e) {
Log.w(TAG, "No memory load current wallpaper", e);
}
@@ -253,7 +246,7 @@
}
}
- private Bitmap getCurrentWallpaperLocked(Context context) {
+ private Bitmap getCurrentWallpaperLocked() {
try {
Bundle params = new Bundle();
ParcelFileDescriptor fd = mService.getWallpaper(this, params);
@@ -265,17 +258,19 @@
BitmapFactory.Options options = new BitmapFactory.Options();
Bitmap bm = BitmapFactory.decodeFileDescriptor(
fd.getFileDescriptor(), null, options);
- return generateBitmap(context, bm, width, height);
+ return generateBitmap(bm, width, height);
} catch (OutOfMemoryError e) {
Log.w(TAG, "Can't decode file", e);
} finally {
try {
fd.close();
} catch (IOException e) {
+ // Ignore
}
}
}
} catch (RemoteException e) {
+ // Ignore
}
return null;
}
@@ -291,27 +286,29 @@
try {
BitmapFactory.Options options = new BitmapFactory.Options();
Bitmap bm = BitmapFactory.decodeStream(is, null, options);
- return generateBitmap(context, bm, width, height);
+ return generateBitmap(bm, width, height);
} catch (OutOfMemoryError e) {
Log.w(TAG, "Can't decode stream", e);
} finally {
try {
is.close();
} catch (IOException e) {
+ // Ignore
}
}
}
} catch (RemoteException e) {
+ // Ignore
}
return null;
}
}
- private static Object mSync = new Object();
+ private static final Object sSync = new Object[0];
private static Globals sGlobals;
static void initGlobals(Looper looper) {
- synchronized (mSync) {
+ synchronized (sSync) {
if (sGlobals == null) {
sGlobals = new Globals(looper);
}
@@ -390,8 +387,7 @@
public Drawable getFastDrawable() {
Bitmap bm = sGlobals.peekWallpaperBitmap(mContext, true);
if (bm != null) {
- Drawable dr = new FastBitmapDrawable(bm);
- return dr;
+ return new FastBitmapDrawable(bm);
}
return null;
}
@@ -406,13 +402,21 @@
public Drawable peekFastDrawable() {
Bitmap bm = sGlobals.peekWallpaperBitmap(mContext, false);
if (bm != null) {
- Drawable dr = new FastBitmapDrawable(bm);
- return dr;
+ return new FastBitmapDrawable(bm);
}
return null;
}
/**
+ * Like {@link #getDrawable()} but returns a Bitmap.
+ *
+ * @hide
+ */
+ public Bitmap getBitmap() {
+ return sGlobals.peekWallpaperBitmap(mContext, true);
+ }
+
+ /**
* 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
@@ -464,6 +468,7 @@
}
}
} catch (RemoteException e) {
+ // Ignore
}
}
@@ -493,6 +498,7 @@
}
}
} catch (RemoteException e) {
+ // Ignore
}
}
@@ -524,6 +530,7 @@
}
}
} catch (RemoteException e) {
+ // Ignore
}
}
@@ -594,6 +601,7 @@
try {
sGlobals.mService.setDimensionHints(minimumWidth, minimumHeight);
} catch (RemoteException e) {
+ // Ignore
}
}
@@ -690,7 +698,7 @@
setResource(com.android.internal.R.drawable.default_wallpaper);
}
- static Bitmap generateBitmap(Context context, Bitmap bm, int width, int height) {
+ static Bitmap generateBitmap(Bitmap bm, int width, int height) {
if (bm == null) {
return null;
}
@@ -717,7 +725,7 @@
if (deltaw > 0 || deltah > 0) {
// We need to scale up so it covers the entire area.
- float scale = 1.0f;
+ float scale;
if (deltaw > deltah) {
scale = width / (float)targetRect.right;
} else {
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index a41a330..bc45945 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -2328,7 +2328,7 @@
* <p>The reference code is as follows.
*
* <pre>
- * public void public void onOrientationChanged(int orientation) {
+ * public void onOrientationChanged(int orientation) {
* if (orientation == ORIENTATION_UNKNOWN) return;
* android.hardware.Camera.CameraInfo info =
* new android.hardware.Camera.CameraInfo();
diff --git a/core/java/android/net/NetworkStats.java b/core/java/android/net/NetworkStats.java
index 272545d..5b883a0 100644
--- a/core/java/android/net/NetworkStats.java
+++ b/core/java/android/net/NetworkStats.java
@@ -313,6 +313,22 @@
}
/**
+ * Return total bytes represented by this snapshot object, usually used when
+ * checking if a {@link #subtract(NetworkStats)} delta passes a threshold.
+ */
+ public long getTotalBytes() {
+ long totalBytes = 0;
+ for (int i = 0; i < size; i++) {
+ // skip specific tags, since already counted in TAG_NONE
+ if (tag[i] != TAG_NONE) continue;
+
+ totalBytes += rxBytes[i];
+ totalBytes += txBytes[i];
+ }
+ return totalBytes;
+ }
+
+ /**
* Subtract the given {@link NetworkStats}, effectively leaving the delta
* between two snapshots in time. Assumes that statistics rows collect over
* time, and that none of them have disappeared.
diff --git a/core/java/android/net/NetworkStatsHistory.java b/core/java/android/net/NetworkStatsHistory.java
index b4f15ac..b19949e 100644
--- a/core/java/android/net/NetworkStatsHistory.java
+++ b/core/java/android/net/NetworkStatsHistory.java
@@ -53,18 +53,21 @@
public class NetworkStatsHistory implements Parcelable {
private static final int VERSION_INIT = 1;
private static final int VERSION_ADD_PACKETS = 2;
+ private static final int VERSION_ADD_ACTIVE = 3;
- 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;
+ public static final int FIELD_ACTIVE_TIME = 0x01;
+ public static final int FIELD_RX_BYTES = 0x02;
+ public static final int FIELD_RX_PACKETS = 0x04;
+ public static final int FIELD_TX_BYTES = 0x08;
+ public static final int FIELD_TX_PACKETS = 0x10;
+ public static final int FIELD_OPERATIONS = 0x20;
public static final int FIELD_ALL = 0xFFFFFFFF;
private long bucketDuration;
private int bucketCount;
private long[] bucketStart;
+ private long[] activeTime;
private long[] rxBytes;
private long[] rxPackets;
private long[] txBytes;
@@ -74,8 +77,9 @@
public static class Entry {
public static final long UNKNOWN = -1;
- public long bucketStart;
public long bucketDuration;
+ public long bucketStart;
+ public long activeTime;
public long rxBytes;
public long rxPackets;
public long txBytes;
@@ -94,6 +98,7 @@
public NetworkStatsHistory(long bucketDuration, int initialSize, int fields) {
this.bucketDuration = bucketDuration;
bucketStart = new long[initialSize];
+ if ((fields & FIELD_ACTIVE_TIME) != 0) activeTime = 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];
@@ -105,6 +110,7 @@
public NetworkStatsHistory(Parcel in) {
bucketDuration = in.readLong();
bucketStart = readLongArray(in);
+ activeTime = readLongArray(in);
rxBytes = readLongArray(in);
rxPackets = readLongArray(in);
txBytes = readLongArray(in);
@@ -117,6 +123,7 @@
public void writeToParcel(Parcel out, int flags) {
out.writeLong(bucketDuration);
writeLongArray(out, bucketStart, bucketCount);
+ writeLongArray(out, activeTime, bucketCount);
writeLongArray(out, rxBytes, bucketCount);
writeLongArray(out, rxPackets, bucketCount);
writeLongArray(out, txBytes, bucketCount);
@@ -138,9 +145,12 @@
bucketCount = bucketStart.length;
break;
}
- case VERSION_ADD_PACKETS: {
+ case VERSION_ADD_PACKETS:
+ case VERSION_ADD_ACTIVE: {
bucketDuration = in.readLong();
bucketStart = readVarLongArray(in);
+ activeTime = (version >= VERSION_ADD_ACTIVE) ? readVarLongArray(in)
+ : new long[bucketStart.length];
rxBytes = readVarLongArray(in);
rxPackets = readVarLongArray(in);
txBytes = readVarLongArray(in);
@@ -156,9 +166,10 @@
}
public void writeToStream(DataOutputStream out) throws IOException {
- out.writeInt(VERSION_ADD_PACKETS);
+ out.writeInt(VERSION_ADD_ACTIVE);
out.writeLong(bucketDuration);
writeVarLongArray(out, bucketStart, bucketCount);
+ writeVarLongArray(out, activeTime, bucketCount);
writeVarLongArray(out, rxBytes, bucketCount);
writeVarLongArray(out, rxPackets, bucketCount);
writeVarLongArray(out, txBytes, bucketCount);
@@ -202,6 +213,7 @@
final Entry entry = recycle != null ? recycle : new Entry();
entry.bucketStart = bucketStart[i];
entry.bucketDuration = bucketDuration;
+ entry.activeTime = getLong(activeTime, i, UNKNOWN);
entry.rxBytes = getLong(rxBytes, i, UNKNOWN);
entry.rxPackets = getLong(rxPackets, i, UNKNOWN);
entry.txBytes = getLong(txBytes, i, UNKNOWN);
@@ -252,8 +264,9 @@
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);
+ final long fracOperations = entry.operations * overlap / duration;
+ addLong(activeTime, i, overlap);
addLong(rxBytes, i, fracRxBytes); entry.rxBytes -= fracRxBytes;
addLong(rxPackets, i, fracRxPackets); entry.rxPackets -= fracRxPackets;
addLong(txBytes, i, fracTxBytes); entry.txBytes -= fracTxBytes;
@@ -311,6 +324,7 @@
if (bucketCount >= bucketStart.length) {
final int newLength = Math.max(bucketStart.length, 10) * 3 / 2;
bucketStart = Arrays.copyOf(bucketStart, newLength);
+ if (activeTime != null) activeTime = Arrays.copyOf(activeTime, 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);
@@ -324,6 +338,7 @@
final int length = bucketCount - index;
System.arraycopy(bucketStart, index, bucketStart, dstPos, length);
+ if (activeTime != null) System.arraycopy(activeTime, index, activeTime, 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);
@@ -332,6 +347,7 @@
}
bucketStart[index] = start;
+ setLong(activeTime, index, 0L);
setLong(rxBytes, index, 0L);
setLong(rxPackets, index, 0L);
setLong(txBytes, index, 0L);
@@ -357,6 +373,7 @@
if (i > 0) {
final int length = bucketStart.length;
bucketStart = Arrays.copyOfRange(bucketStart, i, length);
+ if (activeTime != null) activeTime = Arrays.copyOfRange(activeTime, 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);
@@ -380,8 +397,9 @@
*/
public Entry getValues(long start, long end, long now, Entry recycle) {
final Entry entry = recycle != null ? recycle : new Entry();
- entry.bucketStart = start;
entry.bucketDuration = end - start;
+ entry.bucketStart = start;
+ entry.activeTime = activeTime != null ? 0 : UNKNOWN;
entry.rxBytes = rxBytes != null ? 0 : UNKNOWN;
entry.rxPackets = rxPackets != null ? 0 : UNKNOWN;
entry.txBytes = txBytes != null ? 0 : UNKNOWN;
@@ -404,6 +422,7 @@
if (overlap <= 0) continue;
// integer math each time is faster than floating point
+ if (activeTime != null) entry.activeTime += activeTime[i] * overlap / bucketDuration;
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;
@@ -463,6 +482,7 @@
for (int i = start; i < bucketCount; i++) {
pw.print(prefix);
pw.print(" bucketStart="); pw.print(bucketStart[i]);
+ if (activeTime != null) pw.print(" activeTime="); pw.print(activeTime[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]);
diff --git a/core/java/android/net/TrafficStats.java b/core/java/android/net/TrafficStats.java
index c2c5c18..ec3b1e1 100644
--- a/core/java/android/net/TrafficStats.java
+++ b/core/java/android/net/TrafficStats.java
@@ -198,6 +198,18 @@
}
/**
+ * Increment count of network operations performed under the accounting tag
+ * currently active on the calling thread. This can be used to derive
+ * bytes-per-operation.
+ *
+ * @param operationCount Number of operations to increment count by.
+ */
+ public static void incrementOperationCount(int operationCount) {
+ final int tag = getThreadStatsTag();
+ incrementOperationCount(tag, operationCount);
+ }
+
+ /**
* Increment count of network operations performed under the given
* accounting tag. This can be used to derive bytes-per-operation.
*
diff --git a/core/java/android/provider/CalendarContract.java b/core/java/android/provider/CalendarContract.java
index 5b29103..6fe5124 100644
--- a/core/java/android/provider/CalendarContract.java
+++ b/core/java/android/provider/CalendarContract.java
@@ -110,6 +110,12 @@
public static final String EXTRA_EVENT_END_TIME = "endTime";
/**
+ * Intent Extras key: When creating an event, set this to true to create an
+ * all-day event by default
+ */
+ public static final String EXTRA_EVENT_ALL_DAY = "allDay";
+
+ /**
* This authority is used for writing to or querying from the calendar
* provider. Note: This is set at first run and cannot be changed without
* breaking apps that access the provider.
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index 3967aa8..e205f97 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -2692,6 +2692,7 @@
ContentValues cv = new ContentValues();
DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, ACCOUNT_NAME);
DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, ACCOUNT_TYPE);
+ DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, DATA_SET);
DatabaseUtils.cursorLongToContentValuesIfPresent(cursor, cv, _ID);
DatabaseUtils.cursorLongToContentValuesIfPresent(cursor, cv, DIRTY);
DatabaseUtils.cursorLongToContentValuesIfPresent(cursor, cv, VERSION);
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 15c57e6..0c791e1 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -38,6 +38,7 @@
import android.os.Bundle;
import android.os.RemoteException;
import android.os.SystemProperties;
+import android.speech.tts.TextToSpeech;
import android.text.TextUtils;
import android.util.AndroidException;
import android.util.Log;
@@ -1062,7 +1063,7 @@
public static void clearConfiguration(Configuration inoutConfig) {
inoutConfig.fontScale = 0;
}
-
+
/**
* Convenience function to write a batch of configuration-related
* settings from a {@link Configuration} object.
@@ -2781,7 +2782,11 @@
* of the application settings.
* 1 = override application settings,
* 0 = use application settings (if specified).
+ *
+ * @deprecated The value of this setting is no longer respected by
+ * the framework text to speech APIs as of the Ice Cream Sandwich release.
*/
+ @Deprecated
public static final String TTS_USE_DEFAULTS = "tts_use_defaults";
/**
@@ -2801,24 +2806,46 @@
/**
* Default text-to-speech language.
+ *
+ * @deprecated this setting is no longer in use, as of the Ice Cream
+ * Sandwich release. Apps should never need to read this setting directly,
+ * instead can query the TextToSpeech framework classes for the default
+ * locale. {@link TextToSpeech#getLanguage()}.
*/
+ @Deprecated
public static final String TTS_DEFAULT_LANG = "tts_default_lang";
/**
* Default text-to-speech country.
+ *
+ * @deprecated this setting is no longer in use, as of the Ice Cream
+ * Sandwich release. Apps should never need to read this setting directly,
+ * instead can query the TextToSpeech framework classes for the default
+ * locale. {@link TextToSpeech#getLanguage()}.
*/
+ @Deprecated
public static final String TTS_DEFAULT_COUNTRY = "tts_default_country";
/**
* Default text-to-speech locale variant.
+ *
+ * @deprecated this setting is no longer in use, as of the Ice Cream
+ * Sandwich release. Apps should never need to read this setting directly,
+ * instead can query the TextToSpeech framework classes for the
+ * locale that is in use {@link TextToSpeech#getLanguage()}.
*/
+ @Deprecated
public static final String TTS_DEFAULT_VARIANT = "tts_default_variant";
/**
* Stores the default tts locales on a per engine basis. Stored as
* a comma seperated list of values, each value being of the form
* {@code engine_name:locale} for example,
- * {@code com.foo.ttsengine:eng-USA,com.bar.ttsengine:esp-ESP}.
+ * {@code com.foo.ttsengine:eng-USA,com.bar.ttsengine:esp-ESP}. This
+ * supersedes {@link #TTS_DEFAULT_LANG}, {@link #TTS_DEFAULT_COUNTRY} and
+ * {@link #TTS_DEFAULT_VARIANT}. Apps should never need to read this
+ * setting directly, and can query the TextToSpeech framework classes
+ * for the locale that is in use.
*
* @hide
*/
@@ -3785,6 +3812,13 @@
"selected_spell_checker_subtype";
/**
+ * The {@link ComponentName} string whether spell checker is enabled or not.
+ *
+ * @hide
+ */
+ public static final String SPELL_CHECKER_ENABLED = "spell_checker_enabled";
+
+ /**
* What happens when the user presses the Power button while in-call
* and the screen is on.<br/>
* <b>Values:</b><br/>
@@ -4007,6 +4041,7 @@
TTS_DEFAULT_LANG,
TTS_DEFAULT_COUNTRY,
TTS_ENABLED_PLUGINS,
+ TTS_DEFAULT_LOCALE,
WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON,
WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY,
WIFI_NUM_OPEN_NETWORKS_KEPT,
diff --git a/core/java/android/text/SpannableStringBuilder.java b/core/java/android/text/SpannableStringBuilder.java
index 6bde802..5fed775 100644
--- a/core/java/android/text/SpannableStringBuilder.java
+++ b/core/java/android/text/SpannableStringBuilder.java
@@ -16,21 +16,18 @@
package android.text;
-import com.android.internal.util.ArrayUtils;
-
import android.graphics.Canvas;
import android.graphics.Paint;
-import android.text.style.SuggestionSpan;
+
+import com.android.internal.util.ArrayUtils;
import java.lang.reflect.Array;
/**
* This is the class for text whose content and markup can both be changed.
*/
-public class SpannableStringBuilder
-implements CharSequence, GetChars, Spannable, Editable, Appendable,
- GraphicsOperations
-{
+public class SpannableStringBuilder implements CharSequence, GetChars, Spannable, Editable,
+ Appendable, GraphicsOperations {
/**
* Create a new SpannableStringBuilder with empty contents
*/
@@ -111,8 +108,7 @@
if (where < 0) {
throw new IndexOutOfBoundsException("charAt: " + where + " < 0");
} else if (where >= len) {
- throw new IndexOutOfBoundsException("charAt: " + where +
- " >= length " + len);
+ throw new IndexOutOfBoundsException("charAt: " + where + " >= length " + len);
}
if (where >= mGapStart)
@@ -266,8 +262,7 @@
return append(String.valueOf(text));
}
- private int change(int start, int end,
- CharSequence tb, int tbstart, int tbend) {
+ private int change(int start, int end, CharSequence tb, int tbstart, int tbend) {
return change(true, start, end, tb, tbstart, tbend);
}
@@ -277,8 +272,9 @@
int ret = tbend - tbstart;
TextWatcher[] recipients = null;
- if (notify)
+ if (notify) {
recipients = sendTextWillChange(start, end - start, tbend - tbstart);
+ }
for (int i = mSpanCount - 1; i >= 0; i--) {
if ((mSpanFlags[i] & SPAN_PARAGRAPH) == SPAN_PARAGRAPH) {
@@ -353,7 +349,6 @@
// no need for span fixup on pure insertion
if (tbend > tbstart && end - start == 0) {
if (notify) {
- removeSuggestionSpans(start, end);
sendTextChange(recipients, start, end - start, tbend - tbstart);
sendTextHasChanged(recipients);
}
@@ -388,7 +383,6 @@
if (mSpanEnds[i] < mSpanStarts[i]) {
removeSpan(i);
}
- removeSuggestionSpans(start, end);
}
if (notify) {
@@ -399,30 +393,26 @@
return ret;
}
- /**
- * Removes the SuggestionSpan that overlap the [start, end] range, and that would
- * not make sense anymore after the change.
- */
- private void removeSuggestionSpans(int start, int end) {
- for (int i = mSpanCount - 1; i >= 0; i--) {
- final int spanEnd = mSpanEnds[i];
- final int spanSpart = mSpanStarts[i];
- if ((mSpans[i] instanceof SuggestionSpan) && (
- (spanSpart < start && spanEnd > start) ||
- (spanSpart < end && spanEnd > end))) {
- removeSpan(i);
- }
- }
- }
-
private void removeSpan(int i) {
- // XXX send notification on removal
- System.arraycopy(mSpans, i + 1, mSpans, i, mSpanCount - (i + 1));
- System.arraycopy(mSpanStarts, i + 1, mSpanStarts, i, mSpanCount - (i + 1));
- System.arraycopy(mSpanEnds, i + 1, mSpanEnds, i, mSpanCount - (i + 1));
- System.arraycopy(mSpanFlags, i + 1, mSpanFlags, i, mSpanCount - (i + 1));
+ Object object = mSpans[i];
+
+ int start = mSpanStarts[i];
+ int end = mSpanEnds[i];
+
+ if (start > mGapStart) start -= mGapLength;
+ if (end > mGapStart) end -= mGapLength;
+
+ int count = mSpanCount - (i + 1);
+ System.arraycopy(mSpans, i + 1, mSpans, i, count);
+ System.arraycopy(mSpanStarts, i + 1, mSpanStarts, i, count);
+ System.arraycopy(mSpanEnds, i + 1, mSpanEnds, i, count);
+ System.arraycopy(mSpanFlags, i + 1, mSpanFlags, i, count);
mSpanCount--;
+
+ mSpans[mSpanCount] = null;
+
+ sendSpanRemoved(object, start, end);
}
// Documentation from interface
@@ -462,11 +452,10 @@
moveGapTo(end);
TextWatcher[] recipients;
- recipients = sendTextWillChange(start, end - start,
- tbend - tbstart);
-
int origlen = end - start;
+ recipients = sendTextWillChange(start, origlen, tbend - tbstart);
+
if (mGapLength < 2)
resizeFor(length() + 1);
@@ -486,11 +475,9 @@
new Exception("mGapLength < 1").printStackTrace();
}
- int oldlen = (end + 1) - start;
-
int inserted = change(false, start + 1, start + 1, tb, tbstart, tbend);
change(false, start, start + 1, "", 0, 0);
- change(false, start + inserted, start + inserted + oldlen - 1, "", 0, 0);
+ change(false, start + inserted, start + inserted + origlen, "", 0, 0);
/*
* Special case to keep the cursor in the same position
@@ -515,13 +502,12 @@
off = off * inserted / (end - start);
selend = (int) off + start;
- setSpan(false, Selection.SELECTION_END, selend, selend,
- Spanned.SPAN_POINT_POINT);
+ setSpan(false, Selection.SELECTION_END, selend, selend, Spanned.SPAN_POINT_POINT);
}
-
sendTextChange(recipients, start, origlen, inserted);
sendTextHasChanged(recipients);
}
+
return this;
}
@@ -534,8 +520,7 @@
setSpan(true, what, start, end, flags);
}
- private void setSpan(boolean send,
- Object what, int start, int end, int flags) {
+ private void setSpan(boolean send, Object what, int start, int end, int flags) {
int nstart = start;
int nend = end;
@@ -546,8 +531,7 @@
char c = charAt(start - 1);
if (c != '\n')
- throw new RuntimeException(
- "PARAGRAPH span must start at paragraph boundary");
+ throw new RuntimeException("PARAGRAPH span must start at paragraph boundary");
}
}
@@ -556,23 +540,22 @@
char c = charAt(end - 1);
if (c != '\n')
- throw new RuntimeException(
- "PARAGRAPH span must end at paragraph boundary");
+ throw new RuntimeException("PARAGRAPH span must end at paragraph boundary");
}
}
- if (start > mGapStart)
+ if (start > mGapStart) {
start += mGapLength;
- else if (start == mGapStart) {
+ } else if (start == mGapStart) {
int flag = (flags & START_MASK) >> START_SHIFT;
if (flag == POINT || (flag == PARAGRAPH && start == length()))
start += mGapLength;
}
- if (end > mGapStart)
+ if (end > mGapStart) {
end += mGapLength;
- else if (end == mGapStart) {
+ } else if (end == mGapStart) {
int flag = (flags & END_MASK);
if (flag == POINT || (flag == PARAGRAPH && end == length()))
@@ -637,25 +620,7 @@
public void removeSpan(Object what) {
for (int i = mSpanCount - 1; i >= 0; i--) {
if (mSpans[i] == what) {
- int ostart = mSpanStarts[i];
- int oend = mSpanEnds[i];
-
- if (ostart > mGapStart)
- ostart -= mGapLength;
- if (oend > mGapStart)
- oend -= mGapLength;
-
- int count = mSpanCount - (i + 1);
-
- System.arraycopy(mSpans, i + 1, mSpans, i, count);
- System.arraycopy(mSpanStarts, i + 1, mSpanStarts, i, count);
- System.arraycopy(mSpanEnds, i + 1, mSpanEnds, i, count);
- System.arraycopy(mSpanFlags, i + 1, mSpanFlags, i, count);
-
- mSpanCount--;
- mSpans[mSpanCount] = null;
-
- sendSpanRemoved(what, ostart, oend);
+ removeSpan(i);
return;
}
}
@@ -729,6 +694,8 @@
*/
@SuppressWarnings("unchecked")
public <T> T[] getSpans(int queryStart, int queryEnd, Class<T> kind) {
+ if (kind == null) return ArrayUtils.emptyArray(kind);
+
int spanCount = mSpanCount;
Object[] spans = mSpans;
int[] starts = mSpanStarts;
@@ -742,6 +709,8 @@
T ret1 = null;
for (int i = 0; i < spanCount; i++) {
+ if (!kind.isInstance(spans[i])) continue;
+
int spanStart = starts[i];
int spanEnd = ends[i];
@@ -766,10 +735,6 @@
continue;
}
- if (kind != null && !kind.isInstance(spans[i])) {
- continue;
- }
-
if (count == 0) {
// Safe conversion thanks to the isInstance test above
ret1 = (T) spans[i];
@@ -909,8 +874,7 @@
return recip;
}
- private void sendTextChange(TextWatcher[] recip, int start, int before,
- int after) {
+ private void sendTextChange(TextWatcher[] recip, int start, int before, int after) {
int n = recip.length;
for (int i = 0; i < n; i++) {
@@ -945,8 +909,7 @@
}
private void sendSpanChanged(Object what, int s, int e, int st, int en) {
- SpanWatcher[] recip = getSpans(Math.min(s, st), Math.max(e, en),
- SpanWatcher.class);
+ SpanWatcher[] recip = getSpans(Math.min(s, st), Math.max(e, en), SpanWatcher.class);
int n = recip.length;
for (int i = 0; i < n; i++) {
diff --git a/core/java/android/text/method/WordIterator.java b/core/java/android/text/method/WordIterator.java
index af524ee..0433ec4 100644
--- a/core/java/android/text/method/WordIterator.java
+++ b/core/java/android/text/method/WordIterator.java
@@ -73,6 +73,10 @@
}
};
+ public void forceUpdate() {
+ mCurrentDirty = true;
+ }
+
public void setCharSequence(CharSequence incoming) {
// When incoming is different object, move listeners to new sequence
// and mark as dirty so we reload contents.
diff --git a/core/java/android/text/style/SpellCheckSpan.java b/core/java/android/text/style/SpellCheckSpan.java
new file mode 100644
index 0000000..9b23177
--- /dev/null
+++ b/core/java/android/text/style/SpellCheckSpan.java
@@ -0,0 +1,41 @@
+/*
+ * 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.text.style;
+
+/**
+ * A SpellCheckSpan is an internal data structure created by the TextView's SpellChecker to
+ * annotate portions of the text that are about to or currently being spell checked. They are
+ * automatically removed once the spell check is completed.
+ *
+ * @hide
+ */
+public class SpellCheckSpan {
+
+ private boolean mSpellCheckInProgress;
+
+ public SpellCheckSpan() {
+ mSpellCheckInProgress = false;
+ }
+
+ public void setSpellCheckInProgress() {
+ mSpellCheckInProgress = true;
+ }
+
+ public boolean isSpellCheckInProgress() {
+ return mSpellCheckInProgress;
+ }
+}
diff --git a/core/java/android/text/style/SuggestionSpan.java b/core/java/android/text/style/SuggestionSpan.java
index fb94bc7..ea57f91 100644
--- a/core/java/android/text/style/SuggestionSpan.java
+++ b/core/java/android/text/style/SuggestionSpan.java
@@ -40,7 +40,7 @@
* These spans should typically be created by the input method to provide correction and alternates
* for the text.
*
- * @see TextView#setSuggestionsEnabled(boolean)
+ * @see TextView#isSuggestionsEnabled()
*/
public class SuggestionSpan extends CharacterStyle implements ParcelableSpan {
@@ -76,7 +76,7 @@
* And the current IME might want to specify any IME as the target IME including other IMEs.
*/
- private final int mFlags;
+ private int mFlags;
private final String[] mSuggestions;
private final String mLocaleString;
private final String mNotificationTargetClassName;
@@ -134,8 +134,7 @@
} else {
mNotificationTargetClassName = "";
}
- mHashCode = hashCodeInternal(
- mFlags, mSuggestions, mLocaleString, mNotificationTargetClassName);
+ mHashCode = hashCodeInternal(mSuggestions, mLocaleString, mNotificationTargetClassName);
initStyle(context);
}
@@ -211,6 +210,10 @@
return mFlags;
}
+ public void setFlags(int flags) {
+ mFlags = flags;
+ }
+
@Override
public int describeContents() {
return 0;
@@ -247,10 +250,10 @@
return mHashCode;
}
- private static int hashCodeInternal(int flags, String[] suggestions,String locale,
+ private static int hashCodeInternal(String[] suggestions, String locale,
String notificationTargetClassName) {
- return Arrays.hashCode(new Object[] {SystemClock.uptimeMillis(), flags, suggestions, locale,
- notificationTargetClassName});
+ return Arrays.hashCode(new Object[] {Long.valueOf(SystemClock.uptimeMillis()), suggestions,
+ locale, notificationTargetClassName});
}
public static final Parcelable.Creator<SuggestionSpan> CREATOR =
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index a05637d..926d424 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -21,6 +21,7 @@
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.SurfaceTexture;
+import android.opengl.GLUtils;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.util.Log;
@@ -402,51 +403,6 @@
}
/**
- * Return a string for the EGL error code, or the hex representation
- * if the error is unknown.
- *
- * @param error The EGL error to convert into a String.
- *
- * @return An error string correponding to the EGL error code.
- */
- static String getEGLErrorString(int error) {
- switch (error) {
- case EGL_SUCCESS:
- return "EGL_SUCCESS";
- case EGL_NOT_INITIALIZED:
- return "EGL_NOT_INITIALIZED";
- case EGL_BAD_ACCESS:
- return "EGL_BAD_ACCESS";
- case EGL_BAD_ALLOC:
- return "EGL_BAD_ALLOC";
- case EGL_BAD_ATTRIBUTE:
- return "EGL_BAD_ATTRIBUTE";
- case EGL_BAD_CONFIG:
- return "EGL_BAD_CONFIG";
- case EGL_BAD_CONTEXT:
- return "EGL_BAD_CONTEXT";
- case EGL_BAD_CURRENT_SURFACE:
- return "EGL_BAD_CURRENT_SURFACE";
- case EGL_BAD_DISPLAY:
- return "EGL_BAD_DISPLAY";
- case EGL_BAD_MATCH:
- return "EGL_BAD_MATCH";
- case EGL_BAD_NATIVE_PIXMAP:
- return "EGL_BAD_NATIVE_PIXMAP";
- case EGL_BAD_NATIVE_WINDOW:
- return "EGL_BAD_NATIVE_WINDOW";
- case EGL_BAD_PARAMETER:
- return "EGL_BAD_PARAMETER";
- case EGL_BAD_SURFACE:
- return "EGL_BAD_SURFACE";
- case EGL11.EGL_CONTEXT_LOST:
- return "EGL_CONTEXT_LOST";
- default:
- return "0x" + Integer.toHexString(error);
- }
- }
-
- /**
* Checks for OpenGL errors. If an error has occured, {@link #destroy(boolean)}
* is invoked and the requested flag is turned off. The error code is
* also logged as a warning.
@@ -458,7 +414,7 @@
// something bad has happened revert to
// normal rendering.
fallback(error != EGL11.EGL_CONTEXT_LOST);
- Log.w(LOG_TAG, "EGL error: " + getEGLErrorString(error));
+ Log.w(LOG_TAG, "EGL error: " + GLUtils.getEGLErrorString(error));
}
}
}
@@ -523,14 +479,14 @@
if (sEglDisplay == EGL_NO_DISPLAY) {
throw new RuntimeException("eglGetDisplay failed "
- + getEGLErrorString(sEgl.eglGetError()));
+ + GLUtils.getEGLErrorString(sEgl.eglGetError()));
}
// We can now initialize EGL for that display
int[] version = new int[2];
if (!sEgl.eglInitialize(sEglDisplay, version)) {
throw new RuntimeException("eglInitialize failed " +
- getEGLErrorString(sEgl.eglGetError()));
+ GLUtils.getEGLErrorString(sEgl.eglGetError()));
}
sEglConfig = chooseEglConfig();
@@ -579,7 +535,7 @@
if (!sEgl.eglChooseConfig(sEglDisplay, configSpec, configs, 1, configsCount)) {
throw new IllegalArgumentException("eglChooseConfig failed " +
- getEGLErrorString(sEgl.eglGetError()));
+ GLUtils.getEGLErrorString(sEgl.eglGetError()));
} else if (configsCount[0] > 0) {
if ("choice".equalsIgnoreCase(debug)) {
printConfig(configs[0]);
@@ -647,7 +603,7 @@
*/
if (!sEgl.eglMakeCurrent(sEglDisplay, mEglSurface, mEglSurface, mEglContext)) {
throw new Surface.OutOfResourcesException("eglMakeCurrent failed "
- + getEGLErrorString(sEgl.eglGetError()));
+ + GLUtils.getEGLErrorString(sEgl.eglGetError()));
}
// If mDirtyRegions is set, this means we have an EGL configuration
@@ -734,7 +690,7 @@
return false;
}
throw new RuntimeException("createWindowSurface failed "
- + getEGLErrorString(error));
+ + GLUtils.getEGLErrorString(error));
}
return true;
}
@@ -856,7 +812,7 @@
if (!sEgl.eglMakeCurrent(sEglDisplay, mEglSurface, mEglSurface, mEglContext)) {
fallback(true);
Log.e(LOG_TAG, "eglMakeCurrent failed " +
- getEGLErrorString(sEgl.eglGetError()));
+ GLUtils.getEGLErrorString(sEgl.eglGetError()));
return SURFACE_STATE_ERROR;
} else {
return SURFACE_STATE_UPDATED;
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 17e637c..e97d88f 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -6433,10 +6433,10 @@
if ((flags & VISIBILITY_MASK) == VISIBLE) {
if ((changed & VISIBILITY_MASK) != 0) {
/*
- * If this view is becoming visible, set the DRAWN flag so that
- * the next invalidate() will not be skipped.
+ * If this view is becoming visible, invalidate it in case it changed while
+ * it was not visible.
*/
- mPrivateFlags |= DRAWN;
+ invalidate(true);
needGlobalAttributesUpdate(true);
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index f23c366..6ea863f 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -61,6 +61,7 @@
import android.util.TypedValue;
import android.view.View.MeasureSpec;
import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityInteractionClient;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityManager.AccessibilityStateChangeListener;
import android.view.accessibility.AccessibilityNodeInfo;
@@ -575,7 +576,6 @@
if (hardwareAccelerated) {
if (!HardwareRenderer.isAvailable()) {
- mAttachInfo.mHardwareAccelerationRequested = true;
return;
}
@@ -601,6 +601,13 @@
mAttachInfo.mHardwareRenderer = HardwareRenderer.createGlRenderer(2, translucent);
mAttachInfo.mHardwareAccelerated = mAttachInfo.mHardwareAccelerationRequested
= mAttachInfo.mHardwareRenderer != null;
+ } else {
+ // We would normally have enabled hardware acceleration, but
+ // haven't because we are in the system process. We still want
+ // what is drawn on the screen to behave as if it is accelerated,
+ // so that our preview starting windows visually match what will
+ // actually be drawn by the app.
+ mAttachInfo.mHardwareAccelerationRequested = true;
}
}
}
@@ -879,6 +886,8 @@
host.dispatchAttachedToWindow(attachInfo, 0);
//Log.i(TAG, "Screen on initialized: " + attachInfo.mKeepScreenOn);
+ host.fitSystemWindows(mAttachInfo.mContentInsets);
+
} else {
desiredWindowWidth = frame.width();
desiredWindowHeight = frame.height();
@@ -914,85 +923,15 @@
final Resources res = mView.getContext().getResources();
if (mFirst) {
- host.fitSystemWindows(mAttachInfo.mContentInsets);
// make sure touch mode code executes by setting cached value
// to opposite of the added touch mode.
mAttachInfo.mInTouchMode = !mAddedTouchMode;
ensureTouchModeLocally(mAddedTouchMode);
} else {
- if (!mAttachInfo.mContentInsets.equals(mPendingContentInsets)) {
- if (mWidth > 0 && mHeight > 0 &&
- mSurface != null && mSurface.isValid() &&
- !mAttachInfo.mTurnOffWindowResizeAnim &&
- mAttachInfo.mHardwareRenderer != null &&
- mAttachInfo.mHardwareRenderer.isEnabled() &&
- mAttachInfo.mHardwareRenderer.validate() &&
- lp != null && !PixelFormat.formatHasAlpha(lp.format)) {
-
- disposeResizeBuffer();
-
- boolean completed = false;
- HardwareCanvas canvas = null;
- try {
- if (mResizeBuffer == null) {
- mResizeBuffer = mAttachInfo.mHardwareRenderer.createHardwareLayer(
- mWidth, mHeight, false);
- } else if (mResizeBuffer.getWidth() != mWidth ||
- mResizeBuffer.getHeight() != mHeight) {
- mResizeBuffer.resize(mWidth, mHeight);
- }
- canvas = mResizeBuffer.start(mAttachInfo.mHardwareCanvas);
- canvas.setViewport(mWidth, mHeight);
- canvas.onPreDraw(null);
- final int restoreCount = canvas.save();
-
- canvas.drawColor(0xff000000, PorterDuff.Mode.SRC);
-
- int yoff;
- final boolean scrolling = mScroller != null
- && mScroller.computeScrollOffset();
- if (scrolling) {
- yoff = mScroller.getCurrY();
- mScroller.abortAnimation();
- } else {
- yoff = mScrollY;
- }
-
- canvas.translate(0, -yoff);
- if (mTranslator != null) {
- mTranslator.translateCanvas(canvas);
- }
-
- mView.draw(canvas);
-
- mResizeBufferStartTime = SystemClock.uptimeMillis();
- mResizeBufferDuration = mView.getResources().getInteger(
- com.android.internal.R.integer.config_mediumAnimTime);
- completed = true;
-
- canvas.restoreToCount(restoreCount);
- } catch (OutOfMemoryError e) {
- Log.w(TAG, "Not enough memory for content change anim buffer", e);
- } finally {
- if (canvas != null) {
- canvas.onPostDraw();
- }
- if (mResizeBuffer != null) {
- mResizeBuffer.end(mAttachInfo.mHardwareCanvas);
- if (!completed) {
- mResizeBuffer.destroy();
- mResizeBuffer = null;
- }
- }
- }
- }
- mAttachInfo.mContentInsets.set(mPendingContentInsets);
- host.fitSystemWindows(mAttachInfo.mContentInsets);
+ if (!mPendingContentInsets.equals(mAttachInfo.mContentInsets)) {
insetsChanged = true;
- if (DEBUG_LAYOUT) Log.v(TAG, "Content insets changing to: "
- + mAttachInfo.mContentInsets);
}
- if (!mAttachInfo.mVisibleInsets.equals(mPendingVisibleInsets)) {
+ if (!mPendingVisibleInsets.equals(mAttachInfo.mVisibleInsets)) {
mAttachInfo.mVisibleInsets.set(mPendingVisibleInsets);
if (DEBUG_LAYOUT) Log.v(TAG, "Visible insets changing to: "
+ mAttachInfo.mVisibleInsets);
@@ -1203,6 +1142,71 @@
visibleInsetsChanged = !mPendingVisibleInsets.equals(
mAttachInfo.mVisibleInsets);
if (contentInsetsChanged) {
+ if (mWidth > 0 && mHeight > 0 &&
+ mSurface != null && mSurface.isValid() &&
+ !mAttachInfo.mTurnOffWindowResizeAnim &&
+ mAttachInfo.mHardwareRenderer != null &&
+ mAttachInfo.mHardwareRenderer.isEnabled() &&
+ mAttachInfo.mHardwareRenderer.validate() &&
+ lp != null && !PixelFormat.formatHasAlpha(lp.format)) {
+
+ disposeResizeBuffer();
+
+ boolean completed = false;
+ HardwareCanvas canvas = null;
+ try {
+ if (mResizeBuffer == null) {
+ mResizeBuffer = mAttachInfo.mHardwareRenderer.createHardwareLayer(
+ mWidth, mHeight, false);
+ } else if (mResizeBuffer.getWidth() != mWidth ||
+ mResizeBuffer.getHeight() != mHeight) {
+ mResizeBuffer.resize(mWidth, mHeight);
+ }
+ canvas = mResizeBuffer.start(mAttachInfo.mHardwareCanvas);
+ canvas.setViewport(mWidth, mHeight);
+ canvas.onPreDraw(null);
+ final int restoreCount = canvas.save();
+
+ canvas.drawColor(0xff000000, PorterDuff.Mode.SRC);
+
+ int yoff;
+ final boolean scrolling = mScroller != null
+ && mScroller.computeScrollOffset();
+ if (scrolling) {
+ yoff = mScroller.getCurrY();
+ mScroller.abortAnimation();
+ } else {
+ yoff = mScrollY;
+ }
+
+ canvas.translate(0, -yoff);
+ if (mTranslator != null) {
+ mTranslator.translateCanvas(canvas);
+ }
+
+ mView.draw(canvas);
+
+ mResizeBufferStartTime = SystemClock.uptimeMillis();
+ mResizeBufferDuration = mView.getResources().getInteger(
+ com.android.internal.R.integer.config_mediumAnimTime);
+ completed = true;
+
+ canvas.restoreToCount(restoreCount);
+ } catch (OutOfMemoryError e) {
+ Log.w(TAG, "Not enough memory for content change anim buffer", e);
+ } finally {
+ if (canvas != null) {
+ canvas.onPostDraw();
+ }
+ if (mResizeBuffer != null) {
+ mResizeBuffer.end(mAttachInfo.mHardwareCanvas);
+ if (!completed) {
+ mResizeBuffer.destroy();
+ mResizeBuffer = null;
+ }
+ }
+ }
+ }
mAttachInfo.mContentInsets.set(mPendingContentInsets);
host.fitSystemWindows(mAttachInfo.mContentInsets);
if (DEBUG_LAYOUT) Log.v(TAG, "Content insets changing to: "
@@ -4359,37 +4363,42 @@
}
public void findAccessibilityNodeInfoByAccessibilityId(int accessibilityId,
- int interactionId, IAccessibilityInteractionConnectionCallback callback) {
+ int interactionId, IAccessibilityInteractionConnectionCallback callback,
+ int interrogatingPid, long interrogatingTid) {
if (mViewAncestor.get() != null) {
getAccessibilityInteractionController()
.findAccessibilityNodeInfoByAccessibilityIdClientThread(accessibilityId,
- interactionId, callback);
+ interactionId, callback, interrogatingPid, interrogatingTid);
}
}
public void performAccessibilityAction(int accessibilityId, int action,
- int interactionId, IAccessibilityInteractionConnectionCallback callback) {
+ int interactionId, IAccessibilityInteractionConnectionCallback callback,
+ int interogatingPid, long interrogatingTid) {
if (mViewAncestor.get() != null) {
getAccessibilityInteractionController()
.performAccessibilityActionClientThread(accessibilityId, action, interactionId,
- callback);
+ callback, interogatingPid, interrogatingTid);
}
}
public void findAccessibilityNodeInfoByViewId(int viewId,
- int interactionId, IAccessibilityInteractionConnectionCallback callback) {
+ int interactionId, IAccessibilityInteractionConnectionCallback callback,
+ int interrogatingPid, long interrogatingTid) {
if (mViewAncestor.get() != null) {
getAccessibilityInteractionController()
- .findAccessibilityNodeInfoByViewIdClientThread(viewId, interactionId, callback);
+ .findAccessibilityNodeInfoByViewIdClientThread(viewId, interactionId, callback,
+ interrogatingPid, interrogatingTid);
}
}
public void findAccessibilityNodeInfosByViewText(String text, int accessibilityId,
- int interactionId, IAccessibilityInteractionConnectionCallback callback) {
+ int interactionId, IAccessibilityInteractionConnectionCallback callback,
+ int interrogatingPid, long interrogatingTid) {
if (mViewAncestor.get() != null) {
getAccessibilityInteractionController()
.findAccessibilityNodeInfosByViewTextClientThread(text, accessibilityId,
- interactionId, callback);
+ interactionId, callback, interrogatingPid, interrogatingTid);
}
}
}
@@ -4465,13 +4474,24 @@
}
public void findAccessibilityNodeInfoByAccessibilityIdClientThread(int accessibilityId,
- int interactionId, IAccessibilityInteractionConnectionCallback callback) {
+ int interactionId, IAccessibilityInteractionConnectionCallback callback,
+ int interrogatingPid, long interrogatingTid) {
Message message = Message.obtain();
message.what = DO_FIND_ACCESSIBLITY_NODE_INFO_BY_ACCESSIBILITY_ID;
message.arg1 = accessibilityId;
message.arg2 = interactionId;
message.obj = callback;
- sendMessage(message);
+ // If the interrogation is performed by the same thread as the main UI
+ // thread in this process, set the message as a static reference so
+ // after this call completes the same thread but in the interrogating
+ // client can handle the message to generate the result.
+ if (interrogatingPid == Process.myPid()
+ && interrogatingTid == Looper.getMainLooper().getThread().getId()) {
+ message.setTarget(ViewRootImpl.this);
+ AccessibilityInteractionClient.getInstance().setSameThreadMessage(message);
+ } else {
+ sendMessage(message);
+ }
}
public void findAccessibilityNodeInfoByAccessibilityIdUiThread(Message message) {
@@ -4499,13 +4519,24 @@
}
public void findAccessibilityNodeInfoByViewIdClientThread(int viewId, int interactionId,
- IAccessibilityInteractionConnectionCallback callback) {
+ IAccessibilityInteractionConnectionCallback callback, int interrogatingPid,
+ long interrogatingTid) {
Message message = Message.obtain();
message.what = DO_FIND_ACCESSIBLITY_NODE_INFO_BY_VIEW_ID;
message.arg1 = viewId;
message.arg2 = interactionId;
message.obj = callback;
- sendMessage(message);
+ // If the interrogation is performed by the same thread as the main UI
+ // thread in this process, set the message as a static reference so
+ // after this call completes the same thread but in the interrogating
+ // client can handle the message to generate the result.
+ if (interrogatingPid == Process.myPid()
+ && interrogatingTid == Looper.getMainLooper().getThread().getId()) {
+ message.setTarget(ViewRootImpl.this);
+ AccessibilityInteractionClient.getInstance().setSameThreadMessage(message);
+ } else {
+ sendMessage(message);
+ }
}
public void findAccessibilityNodeInfoByViewIdUiThread(Message message) {
@@ -4532,7 +4563,8 @@
public void findAccessibilityNodeInfosByViewTextClientThread(String text,
int accessibilityViewId, int interactionId,
- IAccessibilityInteractionConnectionCallback callback) {
+ IAccessibilityInteractionConnectionCallback callback, int interrogatingPid,
+ long interrogatingTid) {
Message message = Message.obtain();
message.what = DO_FIND_ACCESSIBLITY_NODE_INFO_BY_VIEW_TEXT;
SomeArgs args = mPool.acquire();
@@ -4541,7 +4573,17 @@
args.argi2 = interactionId;
args.arg2 = callback;
message.obj = args;
- sendMessage(message);
+ // If the interrogation is performed by the same thread as the main UI
+ // thread in this process, set the message as a static reference so
+ // after this call completes the same thread but in the interrogating
+ // client can handle the message to generate the result.
+ if (interrogatingPid == Process.myPid()
+ && interrogatingTid == Looper.getMainLooper().getThread().getId()) {
+ message.setTarget(ViewRootImpl.this);
+ AccessibilityInteractionClient.getInstance().setSameThreadMessage(message);
+ } else {
+ sendMessage(message);
+ }
}
public void findAccessibilityNodeInfosByViewTextUiThread(Message message) {
@@ -4594,7 +4636,8 @@
}
public void performAccessibilityActionClientThread(int accessibilityId, int action,
- int interactionId, IAccessibilityInteractionConnectionCallback callback) {
+ int interactionId, IAccessibilityInteractionConnectionCallback callback,
+ int interogatingPid, long interrogatingTid) {
Message message = Message.obtain();
message.what = DO_PERFORM_ACCESSIBILITY_ACTION;
SomeArgs args = mPool.acquire();
@@ -4603,7 +4646,17 @@
args.argi3 = interactionId;
args.arg1 = callback;
message.obj = args;
- sendMessage(message);
+ // If the interrogation is performed by the same thread as the main UI
+ // thread in this process, set the message as a static reference so
+ // after this call completes the same thread but in the interrogating
+ // client can handle the message to generate the result.
+ if (interogatingPid == Process.myPid()
+ && interrogatingTid == Looper.getMainLooper().getThread().getId()) {
+ message.setTarget(ViewRootImpl.this);
+ AccessibilityInteractionClient.getInstance().setSameThreadMessage(message);
+ } else {
+ sendMessage(message);
+ }
}
public void perfromAccessibilityActionUiThread(Message message) {
diff --git a/core/java/android/view/accessibility/AccessibilityInteractionClient.java b/core/java/android/view/accessibility/AccessibilityInteractionClient.java
new file mode 100644
index 0000000..071701e
--- /dev/null
+++ b/core/java/android/view/accessibility/AccessibilityInteractionClient.java
@@ -0,0 +1,462 @@
+/*
+ ** Copyright 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.view.accessibility;
+
+import android.accessibilityservice.IAccessibilityServiceConnection;
+import android.graphics.Rect;
+import android.os.Message;
+import android.os.RemoteException;
+import android.os.SystemClock;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * This class is a singleton that performs accessibility interaction
+ * which is it queries remote view hierarchies about snapshots of their
+ * views as well requests from these hierarchies to perform certain
+ * actions on their views.
+ *
+ * Rationale: The content retrieval APIs are synchronous from a client's
+ * perspective but internally they are asynchronous. The client thread
+ * calls into the system requesting an action and providing a callback
+ * to receive the result after which it waits up to a timeout for that
+ * result. The system enforces security and the delegates the request
+ * to a given view hierarchy where a message is posted (from a binder
+ * thread) describing what to be performed by the main UI thread the
+ * result of which it delivered via the mentioned callback. However,
+ * the blocked client thread and the main UI thread of the target view
+ * hierarchy can be the same thread, for example an accessibility service
+ * and an activity run in the same process, thus they are executed on the
+ * same main thread. In such a case the retrieval will fail since the UI
+ * thread that has to process the message describing the work to be done
+ * is blocked waiting for a result is has to compute! To avoid this scenario
+ * when making a call the client also passes its process and thread ids so
+ * the accessed view hierarchy can detect if the client making the request
+ * is running in its main UI thread. In such a case the view hierarchy,
+ * specifically the binder thread performing the IPC to it, does not post a
+ * message to be run on the UI thread but passes it to the singleton
+ * interaction client through which all interactions occur and the latter is
+ * responsible to execute the message before starting to wait for the
+ * asynchronous result delivered via the callback. In this case the expected
+ * result is already received so no waiting is performed.
+ *
+ * @hide
+ */
+public final class AccessibilityInteractionClient
+ extends IAccessibilityInteractionConnectionCallback.Stub {
+
+ private static final long TIMEOUT_INTERACTION_MILLIS = 5000;
+
+ private static final Object sStaticLock = new Object();
+
+ private static AccessibilityInteractionClient sInstance;
+
+ private final AtomicInteger mInteractionIdCounter = new AtomicInteger();
+
+ private final Object mInstanceLock = new Object();
+
+ private int mInteractionId = -1;
+
+ private AccessibilityNodeInfo mFindAccessibilityNodeInfoResult;
+
+ private List<AccessibilityNodeInfo> mFindAccessibilityNodeInfosResult;
+
+ private boolean mPerformAccessibilityActionResult;
+
+ private Message mSameThreadMessage;
+
+ private final Rect mTempBounds = new Rect();
+
+ /**
+ * @return The singleton of this class.
+ */
+ public static AccessibilityInteractionClient getInstance() {
+ synchronized (sStaticLock) {
+ if (sInstance == null) {
+ sInstance = new AccessibilityInteractionClient();
+ }
+ return sInstance;
+ }
+ }
+
+ /**
+ * Sets the message to be processed if the interacted view hierarchy
+ * and the interacting client are running in the same thread.
+ *
+ * @param message The message.
+ */
+ public void setSameThreadMessage(Message message) {
+ synchronized (mInstanceLock) {
+ mSameThreadMessage = message;
+ }
+ }
+
+ /**
+ * Finds an {@link AccessibilityNodeInfo} by accessibility id.
+ *
+ * @param connection A connection for interacting with the system.
+ * @param accessibilityWindowId A unique window id.
+ * @param accessibilityViewId A unique View accessibility id.
+ * @return An {@link AccessibilityNodeInfo} if found, null otherwise.
+ */
+ public AccessibilityNodeInfo findAccessibilityNodeInfoByAccessibilityId(
+ IAccessibilityServiceConnection connection, int accessibilityWindowId,
+ int accessibilityViewId) {
+ try {
+ final int interactionId = mInteractionIdCounter.getAndIncrement();
+ final float windowScale = connection.findAccessibilityNodeInfoByAccessibilityId(
+ accessibilityWindowId, accessibilityViewId, interactionId, this,
+ Thread.currentThread().getId());
+ // If the scale is zero the call has failed.
+ if (windowScale > 0) {
+ handleSameThreadMessageIfNeeded();
+ AccessibilityNodeInfo info = getFindAccessibilityNodeInfoResultAndClear(
+ interactionId);
+ finalizeAccessibilityNodeInfo(info, connection, windowScale);
+ return info;
+ }
+ } catch (RemoteException re) {
+ /* ignore */
+ }
+ return null;
+ }
+
+ /**
+ * Finds an {@link AccessibilityNodeInfo} by View id. The search is performed
+ * in the currently active window and starts from the root View in the window.
+ *
+ * @param connection A connection for interacting with the system.
+ * @param id The id of the node.
+ * @return An {@link AccessibilityNodeInfo} if found, null otherwise.
+ */
+ public AccessibilityNodeInfo findAccessibilityNodeInfoByViewIdInActiveWindow(
+ IAccessibilityServiceConnection connection, int viewId) {
+ try {
+ final int interactionId = mInteractionIdCounter.getAndIncrement();
+ final float windowScale = connection.findAccessibilityNodeInfoByViewIdInActiveWindow(
+ viewId, interactionId, this, Thread.currentThread().getId());
+ // If the scale is zero the call has failed.
+ if (windowScale > 0) {
+ handleSameThreadMessageIfNeeded();
+ AccessibilityNodeInfo info = getFindAccessibilityNodeInfoResultAndClear(
+ interactionId);
+ finalizeAccessibilityNodeInfo(info, connection, windowScale);
+ return info;
+ }
+ } catch (RemoteException re) {
+ /* ignore */
+ }
+ return null;
+ }
+
+ /**
+ * Finds {@link AccessibilityNodeInfo}s by View text. The match is case
+ * insensitive containment. The search is performed in the currently
+ * active window and starts from the root View in the window.
+ *
+ * @param connection A connection for interacting with the system.
+ * @param text The searched text.
+ * @return A list of found {@link AccessibilityNodeInfo}s.
+ */
+ public List<AccessibilityNodeInfo> findAccessibilityNodeInfosByViewTextInActiveWindow(
+ IAccessibilityServiceConnection connection, String text) {
+ try {
+ final int interactionId = mInteractionIdCounter.getAndIncrement();
+ final float windowScale = connection.findAccessibilityNodeInfosByViewTextInActiveWindow(
+ text, interactionId, this, Thread.currentThread().getId());
+ // If the scale is zero the call has failed.
+ if (windowScale > 0) {
+ handleSameThreadMessageIfNeeded();
+ List<AccessibilityNodeInfo> infos = getFindAccessibilityNodeInfosResultAndClear(
+ interactionId);
+ finalizeAccessibilityNodeInfos(infos, connection, windowScale);
+ return infos;
+ }
+ } catch (RemoteException re) {
+ /* ignore */
+ }
+ return null;
+ }
+
+ /**
+ * Finds {@link AccessibilityNodeInfo}s by View text. The match is case
+ * insensitive containment. The search is performed in the window whose
+ * id is specified and starts from the View whose accessibility id is
+ * specified.
+ *
+ * @param connection A connection for interacting with the system.
+ * @param text The searched text.
+ * @param accessibilityWindowId A unique window id.
+ * @param accessibilityViewId A unique View accessibility id from where to start the search.
+ * Use {@link android.view.View#NO_ID} to start from the root.
+ * @return A list of found {@link AccessibilityNodeInfo}s.
+ */
+ public List<AccessibilityNodeInfo> findAccessibilityNodeInfosByViewText(
+ IAccessibilityServiceConnection connection, String text, int accessibilityWindowId,
+ int accessibilityViewId) {
+ try {
+ final int interactionId = mInteractionIdCounter.getAndIncrement();
+ final float windowScale = connection.findAccessibilityNodeInfosByViewText(text,
+ accessibilityWindowId, accessibilityViewId, interactionId, this,
+ Thread.currentThread().getId());
+ // If the scale is zero the call has failed.
+ if (windowScale > 0) {
+ handleSameThreadMessageIfNeeded();
+ List<AccessibilityNodeInfo> infos = getFindAccessibilityNodeInfosResultAndClear(
+ interactionId);
+ finalizeAccessibilityNodeInfos(infos, connection, windowScale);
+ return infos;
+ }
+ } catch (RemoteException re) {
+ /* ignore */
+ }
+ return Collections.emptyList();
+ }
+
+ /**
+ * Performs an accessibility action on an {@link AccessibilityNodeInfo}.
+ *
+ * @param connection A connection for interacting with the system.
+ * @param accessibilityWindowId The id of the window.
+ * @param accessibilityViewId A unique View accessibility id.
+ * @param action The action to perform.
+ * @return Whether the action was performed.
+ */
+ public boolean performAccessibilityAction(IAccessibilityServiceConnection connection,
+ int accessibilityWindowId, int accessibilityViewId, int action) {
+ try {
+ final int interactionId = mInteractionIdCounter.getAndIncrement();
+ final boolean success = connection.performAccessibilityAction(
+ accessibilityWindowId, accessibilityViewId, action, interactionId, this,
+ Thread.currentThread().getId());
+ if (success) {
+ handleSameThreadMessageIfNeeded();
+ return getPerformAccessibilityActionResult(interactionId);
+ }
+ } catch (RemoteException re) {
+ /* ignore */
+ }
+ return false;
+ }
+
+ /**
+ * Gets the the result of an async request that returns an {@link AccessibilityNodeInfo}.
+ *
+ * @param interactionId The interaction id to match the result with the request.
+ * @return The result {@link AccessibilityNodeInfo}.
+ */
+ private AccessibilityNodeInfo getFindAccessibilityNodeInfoResultAndClear(int interactionId) {
+ synchronized (mInstanceLock) {
+ final boolean success = waitForResultTimedLocked(interactionId);
+ AccessibilityNodeInfo result = success ? mFindAccessibilityNodeInfoResult : null;
+ clearResultLocked();
+ return result;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setFindAccessibilityNodeInfoResult(AccessibilityNodeInfo info,
+ int interactionId) {
+ synchronized (mInstanceLock) {
+ if (interactionId > mInteractionId) {
+ mFindAccessibilityNodeInfoResult = info;
+ mInteractionId = interactionId;
+ }
+ mInstanceLock.notifyAll();
+ }
+ }
+
+ /**
+ * Gets the the result of an async request that returns {@link AccessibilityNodeInfo}s.
+ *
+ * @param interactionId The interaction id to match the result with the request.
+ * @return The result {@link AccessibilityNodeInfo}s.
+ */
+ private List<AccessibilityNodeInfo> getFindAccessibilityNodeInfosResultAndClear(
+ int interactionId) {
+ synchronized (mInstanceLock) {
+ final boolean success = waitForResultTimedLocked(interactionId);
+ List<AccessibilityNodeInfo> result = success ? mFindAccessibilityNodeInfosResult : null;
+ clearResultLocked();
+ return result;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setFindAccessibilityNodeInfosResult(List<AccessibilityNodeInfo> infos,
+ int interactionId) {
+ synchronized (mInstanceLock) {
+ if (interactionId > mInteractionId) {
+ mFindAccessibilityNodeInfosResult = infos;
+ mInteractionId = interactionId;
+ }
+ mInstanceLock.notifyAll();
+ }
+ }
+
+ /**
+ * Gets the result of a request to perform an accessibility action.
+ *
+ * @param interactionId The interaction id to match the result with the request.
+ * @return Whether the action was performed.
+ */
+ private boolean getPerformAccessibilityActionResult(int interactionId) {
+ synchronized (mInstanceLock) {
+ final boolean success = waitForResultTimedLocked(interactionId);
+ final boolean result = success ? mPerformAccessibilityActionResult : false;
+ clearResultLocked();
+ return result;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setPerformAccessibilityActionResult(boolean succeeded, int interactionId) {
+ synchronized (mInstanceLock) {
+ if (interactionId > mInteractionId) {
+ mPerformAccessibilityActionResult = succeeded;
+ mInteractionId = interactionId;
+ }
+ mInstanceLock.notifyAll();
+ }
+ }
+
+ /**
+ * Clears the result state.
+ */
+ private void clearResultLocked() {
+ mInteractionId = -1;
+ mFindAccessibilityNodeInfoResult = null;
+ mFindAccessibilityNodeInfosResult = null;
+ mPerformAccessibilityActionResult = false;
+ }
+
+ /**
+ * Waits up to a given bound for a result of a request and returns it.
+ *
+ * @param interactionId The interaction id to match the result with the request.
+ * @return Whether the result was received.
+ */
+ private boolean waitForResultTimedLocked(int interactionId) {
+ long waitTimeMillis = TIMEOUT_INTERACTION_MILLIS;
+ final long startTimeMillis = SystemClock.uptimeMillis();
+ while (true) {
+ try {
+ if (mInteractionId == interactionId) {
+ return true;
+ }
+ if (mInteractionId > interactionId) {
+ return false;
+ }
+ final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis;
+ waitTimeMillis = TIMEOUT_INTERACTION_MILLIS - elapsedTimeMillis;
+ if (waitTimeMillis <= 0) {
+ return false;
+ }
+ mInstanceLock.wait(waitTimeMillis);
+ } catch (InterruptedException ie) {
+ /* ignore */
+ }
+ }
+ }
+
+ /**
+ * Applies compatibility scale to the info bounds if it is not equal to one.
+ *
+ * @param info The info whose bounds to scale.
+ * @param scale The scale to apply.
+ */
+ private void applyCompatibilityScaleIfNeeded(AccessibilityNodeInfo info, float scale) {
+ if (scale == 1.0f) {
+ return;
+ }
+ Rect bounds = mTempBounds;
+ info.getBoundsInParent(bounds);
+ bounds.scale(scale);
+ info.setBoundsInParent(bounds);
+
+ info.getBoundsInScreen(bounds);
+ bounds.scale(scale);
+ info.setBoundsInScreen(bounds);
+ }
+
+ /**
+ * Handles the message stored if the interacted and interacting
+ * threads are the same otherwise this is a NOP.
+ */
+ private void handleSameThreadMessageIfNeeded() {
+ Message sameProcessMessage = getSameProcessMessageAndClear();
+ if (sameProcessMessage != null) {
+ sameProcessMessage.getTarget().handleMessage(sameProcessMessage);
+ }
+ }
+
+ /**
+ * Finalize an {@link AccessibilityNodeInfo} before passing it to the client.
+ *
+ * @param info The info.
+ * @param connection The current connection to the system.
+ * @param windowScale The source window compatibility scale.
+ */
+ private void finalizeAccessibilityNodeInfo(AccessibilityNodeInfo info,
+ IAccessibilityServiceConnection connection, float windowScale) {
+ if (info != null) {
+ applyCompatibilityScaleIfNeeded(info, windowScale);
+ info.setConnection(connection);
+ info.setSealed(true);
+ }
+ }
+
+ /**
+ * Finalize {@link AccessibilityNodeInfo}s before passing them to the client.
+ *
+ * @param infos The {@link AccessibilityNodeInfo}s.
+ * @param connection The current connection to the system.
+ * @param windowScale The source window compatibility scale.
+ */
+ private void finalizeAccessibilityNodeInfos(List<AccessibilityNodeInfo> infos,
+ IAccessibilityServiceConnection connection, float windowScale) {
+ if (infos != null) {
+ final int infosCount = infos.size();
+ for (int i = 0; i < infosCount; i++) {
+ AccessibilityNodeInfo info = infos.get(i);
+ finalizeAccessibilityNodeInfo(info, connection, windowScale);
+ }
+ }
+ }
+
+ /**
+ * Gets the message stored if the interacted and interacting
+ * threads are the same.
+ *
+ * @return The message.
+ */
+ private Message getSameProcessMessageAndClear() {
+ synchronized (mInstanceLock) {
+ Message result = mSameThreadMessage;
+ mSameThreadMessage = null;
+ return result;
+ }
+ }
+}
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index 6469b35..f0e8005 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -20,7 +20,6 @@
import android.graphics.Rect;
import android.os.Parcel;
import android.os.Parcelable;
-import android.os.RemoteException;
import android.text.TextUtils;
import android.util.SparseIntArray;
import android.view.View;
@@ -181,13 +180,9 @@
if (!canPerformRequestOverConnection(childAccessibilityViewId)) {
return null;
}
- try {
- return mConnection.findAccessibilityNodeInfoByAccessibilityId(mAccessibilityWindowId,
- childAccessibilityViewId);
- } catch (RemoteException re) {
- /* ignore*/
- }
- return null;
+ AccessibilityInteractionClient client = AccessibilityInteractionClient.getInstance();
+ return client.findAccessibilityNodeInfoByAccessibilityId(mConnection,
+ mAccessibilityWindowId, childAccessibilityViewId);
}
/**
@@ -257,13 +252,9 @@
if (!canPerformRequestOverConnection(mAccessibilityViewId)) {
return false;
}
- try {
- return mConnection.performAccessibilityAction(mAccessibilityWindowId,
- mAccessibilityViewId, action);
- } catch (RemoteException e) {
- /* ignore */
- }
- return false;
+ AccessibilityInteractionClient client = AccessibilityInteractionClient.getInstance();
+ return client.performAccessibilityAction(mConnection, mAccessibilityWindowId,
+ mAccessibilityViewId, action);
}
/**
@@ -284,13 +275,9 @@
if (!canPerformRequestOverConnection(mAccessibilityViewId)) {
return Collections.emptyList();
}
- try {
- return mConnection.findAccessibilityNodeInfosByViewText(text, mAccessibilityWindowId,
- mAccessibilityViewId);
- } catch (RemoteException e) {
- /* ignore */
- }
- return Collections.emptyList();
+ AccessibilityInteractionClient client = AccessibilityInteractionClient.getInstance();
+ return client.findAccessibilityNodeInfosByViewText(mConnection, text,
+ mAccessibilityWindowId, mAccessibilityViewId);
}
/**
@@ -308,13 +295,9 @@
if (!canPerformRequestOverConnection(mAccessibilityViewId)) {
return null;
}
- try {
- return mConnection.findAccessibilityNodeInfoByAccessibilityId(
- mAccessibilityWindowId, mParentAccessibilityViewId);
- } catch (RemoteException e) {
- /* ignore */
- }
- return null;
+ AccessibilityInteractionClient client = AccessibilityInteractionClient.getInstance();
+ return client.findAccessibilityNodeInfoByAccessibilityId(mConnection,
+ mAccessibilityWindowId, mParentAccessibilityViewId);
}
/**
diff --git a/core/java/android/view/accessibility/AccessibilityRecord.java b/core/java/android/view/accessibility/AccessibilityRecord.java
index 210106f..afd7473 100644
--- a/core/java/android/view/accessibility/AccessibilityRecord.java
+++ b/core/java/android/view/accessibility/AccessibilityRecord.java
@@ -18,7 +18,6 @@
import android.accessibilityservice.IAccessibilityServiceConnection;
import android.os.Parcelable;
-import android.os.RemoteException;
import android.view.View;
import java.util.ArrayList;
@@ -127,13 +126,9 @@
if (mSourceWindowId == View.NO_ID || mSourceViewId == View.NO_ID || mConnection == null) {
return null;
}
- try {
- return mConnection.findAccessibilityNodeInfoByAccessibilityId(mSourceWindowId,
- mSourceViewId);
- } catch (RemoteException e) {
- /* ignore */
- }
- return null;
+ AccessibilityInteractionClient client = AccessibilityInteractionClient.getInstance();
+ return client.findAccessibilityNodeInfoByAccessibilityId(mConnection, mSourceWindowId,
+ mSourceViewId);
}
/**
diff --git a/core/java/android/view/accessibility/IAccessibilityInteractionCallback.aidl b/core/java/android/view/accessibility/IAccessibilityInteractionCallback.aidl
new file mode 100644
index 0000000..eeab4f2
--- /dev/null
+++ b/core/java/android/view/accessibility/IAccessibilityInteractionCallback.aidl
@@ -0,0 +1,54 @@
+/*
+ * 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.view.accessibility;
+
+import android.view.accessibility.AccessibilityNodeInfo;
+import java.util.List;
+
+/**
+ * Callback for specifying the result for an asynchronous request made
+ * via calling a method on IAccessibilityInteractionCallback.
+ *
+ * @hide
+ */
+oneway interface IAccessibilityInteractionCallback {
+
+ /**
+ * Sets the result of an async request that returns an {@link AccessibilityNodeInfo}.
+ *
+ * @param infos The result {@link AccessibilityNodeInfo}.
+ * @param interactionId The interaction id to match the result with the request.
+ */
+ void setFindAccessibilityNodeInfoResult(in AccessibilityNodeInfo info, int interactionId);
+
+ /**
+ * Sets the result of an async request that returns {@link AccessibilityNodeInfo}s.
+ *
+ * @param infos The result {@link AccessibilityNodeInfo}s.
+ * @param interactionId The interaction id to match the result with the request.
+ */
+ void setFindAccessibilityNodeInfosResult(in List<AccessibilityNodeInfo> infos,
+ int interactionId);
+
+ /**
+ * Sets the result of a request to perform an accessibility action.
+ *
+ * @param Whether the action was performed.
+ * @param interactionId The interaction id to match the result with the request.
+ */
+ void setPerformAccessibilityActionResult(boolean succeeded, int interactionId);
+}
diff --git a/core/java/android/view/accessibility/IAccessibilityInteractionConnection.aidl b/core/java/android/view/accessibility/IAccessibilityInteractionConnection.aidl
index d35186b..535d594 100644
--- a/core/java/android/view/accessibility/IAccessibilityInteractionConnection.aidl
+++ b/core/java/android/view/accessibility/IAccessibilityInteractionConnection.aidl
@@ -28,14 +28,18 @@
oneway interface IAccessibilityInteractionConnection {
void findAccessibilityNodeInfoByAccessibilityId(int accessibilityViewId, int interactionId,
- IAccessibilityInteractionConnectionCallback callback);
+ IAccessibilityInteractionConnectionCallback callback,
+ int interrogatingPid, long interrogatingTid);
void findAccessibilityNodeInfoByViewId(int id, int interactionId,
- IAccessibilityInteractionConnectionCallback callback);
+ IAccessibilityInteractionConnectionCallback callback,
+ int interrogatingPid, long interrogatingTid);
void findAccessibilityNodeInfosByViewText(String text, int accessibilityViewId,
- int interactionId, IAccessibilityInteractionConnectionCallback callback);
+ int interactionId, IAccessibilityInteractionConnectionCallback callback,
+ int interrogatingPid, long interrogatingTid);
void performAccessibilityAction(int accessibilityId, int action, int interactionId,
- IAccessibilityInteractionConnectionCallback callback);
+ IAccessibilityInteractionConnectionCallback callback, int interrogatingPid,
+ long interrogatingTid);
}
diff --git a/core/java/android/view/accessibility/IAccessibilityInteractionConnectionCallback.aidl b/core/java/android/view/accessibility/IAccessibilityInteractionConnectionCallback.aidl
index 9c5e8dc..c1a3ab7 100644
--- a/core/java/android/view/accessibility/IAccessibilityInteractionConnectionCallback.aidl
+++ b/core/java/android/view/accessibility/IAccessibilityInteractionConnectionCallback.aidl
@@ -27,10 +27,28 @@
*/
oneway interface IAccessibilityInteractionConnectionCallback {
+ /**
+ * Sets the result of an async request that returns an {@link AccessibilityNodeInfo}.
+ *
+ * @param infos The result {@link AccessibilityNodeInfo}.
+ * @param interactionId The interaction id to match the result with the request.
+ */
void setFindAccessibilityNodeInfoResult(in AccessibilityNodeInfo info, int interactionId);
+ /**
+ * Sets the result of an async request that returns {@link AccessibilityNodeInfo}s.
+ *
+ * @param infos The result {@link AccessibilityNodeInfo}s.
+ * @param interactionId The interaction id to match the result with the request.
+ */
void setFindAccessibilityNodeInfosResult(in List<AccessibilityNodeInfo> infos,
int interactionId);
+ /**
+ * Sets the result of a request to perform an accessibility action.
+ *
+ * @param Whether the action was performed.
+ * @param interactionId The interaction id to match the result with the request.
+ */
void setPerformAccessibilityActionResult(boolean succeeded, int interactionId);
}
diff --git a/core/java/android/view/animation/Animation.java b/core/java/android/view/animation/Animation.java
index f4b9252..c1eec6f 100644
--- a/core/java/android/view/animation/Animation.java
+++ b/core/java/android/view/animation/Animation.java
@@ -441,6 +441,7 @@
*/
public void scaleCurrentDuration(float scale) {
mDuration = (long) (mDuration * scale);
+ mStartOffset = (long) (mStartOffset * scale);
}
/**
diff --git a/core/java/android/view/textservice/SuggestionsInfo.java b/core/java/android/view/textservice/SuggestionsInfo.java
index ed0f89d..62a06b9 100644
--- a/core/java/android/view/textservice/SuggestionsInfo.java
+++ b/core/java/android/view/textservice/SuggestionsInfo.java
@@ -16,6 +16,8 @@
package android.view.textservice;
+import com.android.internal.util.ArrayUtils;
+
import android.os.Parcel;
import android.os.Parcelable;
@@ -23,7 +25,7 @@
* This class contains a metadata of suggestions from the text service
*/
public final class SuggestionsInfo implements Parcelable {
- private static final String[] EMPTY = new String[0];
+ private static final String[] EMPTY = ArrayUtils.emptyArray(String.class);
/**
* Flag of the attributes of the suggestions that can be obtained by
diff --git a/core/java/android/view/textservice/TextServicesManager.java b/core/java/android/view/textservice/TextServicesManager.java
index bb13052..5dca348 100644
--- a/core/java/android/view/textservice/TextServicesManager.java
+++ b/core/java/android/view/textservice/TextServicesManager.java
@@ -170,5 +170,26 @@
}
}
+ /**
+ * @hide
+ */
+ public void setSpellCheckerEnabled(boolean enabled) {
+ try {
+ sService.setSpellCheckerEnabled(enabled);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error in setSpellCheckerSubtype:" + e);
+ }
+ }
+ /**
+ * @hide
+ */
+ public boolean isSpellCheckerEnabled() {
+ try {
+ return sService.isSpellCheckerEnabled();
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error in setSpellCheckerSubtype:" + e);
+ return false;
+ }
+ }
}
diff --git a/core/java/android/widget/SpellChecker.java b/core/java/android/widget/SpellChecker.java
new file mode 100644
index 0000000..5e3b956
--- /dev/null
+++ b/core/java/android/widget/SpellChecker.java
@@ -0,0 +1,226 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+
+package android.widget;
+
+import android.content.Context;
+import android.text.Editable;
+import android.text.Selection;
+import android.text.Spanned;
+import android.text.style.SpellCheckSpan;
+import android.text.style.SuggestionSpan;
+import android.util.Log;
+import android.view.textservice.SpellCheckerSession;
+import android.view.textservice.SpellCheckerSession.SpellCheckerSessionListener;
+import android.view.textservice.SuggestionsInfo;
+import android.view.textservice.TextInfo;
+import android.view.textservice.TextServicesManager;
+
+import com.android.internal.util.ArrayUtils;
+
+import java.util.Locale;
+
+
+/**
+ * Helper class for TextView. Bridge between the TextView and the Dictionnary service.
+ *
+ * @hide
+ */
+public class SpellChecker implements SpellCheckerSessionListener {
+ private static final String LOG_TAG = "SpellChecker";
+ private static final boolean DEBUG_SPELL_CHECK = false;
+ private static final int DELAY_BEFORE_SPELL_CHECK = 400; // milliseconds
+
+ private final TextView mTextView;
+
+ final SpellCheckerSession spellCheckerSession;
+ final int mCookie;
+
+ // Paired arrays for the (id, spellCheckSpan) pair. mIndex is the next available position
+ private int[] mIds;
+ private SpellCheckSpan[] mSpellCheckSpans;
+ // The actual current number of used slots in the above arrays
+ private int mLength;
+
+ private int mSpanSequenceCounter = 0;
+ private Runnable mChecker;
+
+ public SpellChecker(TextView textView) {
+ mTextView = textView;
+
+ final TextServicesManager textServicesManager = (TextServicesManager) textView.getContext().
+ getSystemService(Context.TEXT_SERVICES_MANAGER_SERVICE);
+ spellCheckerSession = textServicesManager.newSpellCheckerSession(
+ null /* not currently used by the textServicesManager */, Locale.getDefault(),
+ this, true /* means use the languages defined in Settings */);
+ mCookie = hashCode();
+
+ // Arbitrary: 4 simultaneous spell check spans. Will automatically double size on demand
+ final int size = ArrayUtils.idealObjectArraySize(4);
+ mIds = new int[size];
+ mSpellCheckSpans = new SpellCheckSpan[size];
+ mLength = 0;
+ }
+
+ public void addSpellCheckSpan(SpellCheckSpan spellCheckSpan) {
+ int length = mIds.length;
+ if (mLength >= length) {
+ final int newSize = length * 2;
+ int[] newIds = new int[newSize];
+ SpellCheckSpan[] newSpellCheckSpans = new SpellCheckSpan[newSize];
+ System.arraycopy(mIds, 0, newIds, 0, length);
+ System.arraycopy(mSpellCheckSpans, 0, newSpellCheckSpans, 0, length);
+ mIds = newIds;
+ mSpellCheckSpans = newSpellCheckSpans;
+ }
+
+ mIds[mLength] = mSpanSequenceCounter++;
+ mSpellCheckSpans[mLength] = spellCheckSpan;
+ mLength++;
+
+ if (DEBUG_SPELL_CHECK) {
+ final Editable mText = (Editable) mTextView.getText();
+ int start = mText.getSpanStart(spellCheckSpan);
+ int end = mText.getSpanEnd(spellCheckSpan);
+ if (start >= 0 && end >= 0) {
+ Log.d(LOG_TAG, "Schedule check " + mText.subSequence(start, end));
+ } else {
+ Log.d(LOG_TAG, "Schedule check EMPTY!");
+ }
+ }
+
+ scheduleSpellCheck();
+ }
+
+ public void removeSpellCheckSpan(SpellCheckSpan spellCheckSpan) {
+ for (int i = 0; i < mLength; i++) {
+ if (mSpellCheckSpans[i] == spellCheckSpan) {
+ removeAtIndex(i);
+ return;
+ }
+ }
+ }
+
+ private void removeAtIndex(int i) {
+ System.arraycopy(mIds, i + 1, mIds, i, mLength - i - 1);
+ System.arraycopy(mSpellCheckSpans, i + 1, mSpellCheckSpans, i, mLength - i - 1);
+ mLength--;
+ }
+
+ public void onSelectionChanged() {
+ scheduleSpellCheck();
+ }
+
+ private void scheduleSpellCheck() {
+ if (mLength == 0) return;
+ if (mChecker != null) {
+ mTextView.removeCallbacks(mChecker);
+ }
+ if (mChecker == null) {
+ mChecker = new Runnable() {
+ public void run() {
+ spellCheck();
+ }
+ };
+ }
+ mTextView.postDelayed(mChecker, DELAY_BEFORE_SPELL_CHECK);
+ }
+
+ private void spellCheck() {
+ final Editable editable = (Editable) mTextView.getText();
+ final int selectionStart = Selection.getSelectionStart(editable);
+ final int selectionEnd = Selection.getSelectionEnd(editable);
+
+ TextInfo[] textInfos = new TextInfo[mLength];
+ int textInfosCount = 0;
+
+ for (int i = 0; i < mLength; i++) {
+ SpellCheckSpan spellCheckSpan = mSpellCheckSpans[i];
+
+ if (spellCheckSpan.isSpellCheckInProgress()) continue;
+
+ final int start = editable.getSpanStart(spellCheckSpan);
+ final int end = editable.getSpanEnd(spellCheckSpan);
+
+ // Do not check this word if the user is currently editing it
+ if (start >= 0 && end >= 0 && (selectionEnd < start || selectionStart > end)) {
+ final String word = editable.subSequence(start, end).toString();
+ spellCheckSpan.setSpellCheckInProgress();
+ textInfos[textInfosCount++] = new TextInfo(word, mCookie, mIds[i]);
+ }
+ }
+
+ if (textInfosCount > 0) {
+ if (textInfosCount < mLength) {
+ TextInfo[] textInfosCopy = new TextInfo[textInfosCount];
+ System.arraycopy(textInfos, 0, textInfosCopy, 0, textInfosCount);
+ textInfos = textInfosCopy;
+ }
+ spellCheckerSession.getSuggestions(textInfos, SuggestionSpan.SUGGESTIONS_MAX_SIZE,
+ false /* TODO Set sequentialWords to true for initial spell check */);
+ }
+ }
+
+ @Override
+ public void onGetSuggestions(SuggestionsInfo[] results) {
+ final Editable editable = (Editable) mTextView.getText();
+ for (int i = 0; i < results.length; i++) {
+ SuggestionsInfo suggestionsInfo = results[i];
+ if (suggestionsInfo.getCookie() != mCookie) continue;
+
+ final int sequenceNumber = suggestionsInfo.getSequence();
+ // Starting from the end, to limit the number of array copy while removing
+ for (int j = mLength - 1; j >= 0; j--) {
+ if (sequenceNumber == mIds[j]) {
+ SpellCheckSpan spellCheckSpan = mSpellCheckSpans[j];
+ final int attributes = suggestionsInfo.getSuggestionsAttributes();
+ boolean isInDictionary =
+ ((attributes & SuggestionsInfo.RESULT_ATTR_IN_THE_DICTIONARY) > 0);
+ boolean looksLikeTypo =
+ ((attributes & SuggestionsInfo.RESULT_ATTR_LOOKS_LIKE_TYPO) > 0);
+
+ if (DEBUG_SPELL_CHECK) {
+ final int start = editable.getSpanStart(spellCheckSpan);
+ final int end = editable.getSpanEnd(spellCheckSpan);
+ Log.d(LOG_TAG, "Result sequence=" + suggestionsInfo.getSequence() + " " +
+ editable.subSequence(start, end) +
+ "\t" + (isInDictionary?"IN_DICT" : "NOT_DICT") +
+ "\t" + (looksLikeTypo?"TYPO" : "NOT_TYPO"));
+ }
+
+ if (!isInDictionary && looksLikeTypo) {
+ String[] suggestions = getSuggestions(suggestionsInfo);
+ if (suggestions.length > 0) {
+ SuggestionSpan suggestionSpan = new SuggestionSpan(
+ mTextView.getContext(), suggestions,
+ SuggestionSpan.FLAG_EASY_CORRECT |
+ SuggestionSpan.FLAG_MISSPELLED);
+ final int start = editable.getSpanStart(spellCheckSpan);
+ final int end = editable.getSpanEnd(spellCheckSpan);
+ editable.setSpan(suggestionSpan, start, end,
+ Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+ // TODO limit to the word rectangle region
+ mTextView.invalidate();
+
+ if (DEBUG_SPELL_CHECK) {
+ String suggestionsString = "";
+ for (String s : suggestions) { suggestionsString += s + "|"; }
+ Log.d(LOG_TAG, " Suggestions for " + sequenceNumber + " " +
+ editable.subSequence(start, end)+ " " + suggestionsString);
+ }
+ }
+ }
+ editable.removeSpan(spellCheckSpan);
+ }
+ }
+ }
+ }
+
+ private static String[] getSuggestions(SuggestionsInfo suggestionsInfo) {
+ final int len = Math.max(0, suggestionsInfo.getSuggestionsCount());
+ String[] suggestions = new String[len];
+ for (int j = 0; j < len; ++j) {
+ suggestions[j] = suggestionsInfo.getSuggestionAt(j);
+ }
+ return suggestions;
+ }
+}
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 662b964..683a984 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -61,11 +61,6 @@
import android.text.StaticLayout;
import android.text.TextDirectionHeuristic;
import android.text.TextDirectionHeuristics;
-import android.text.TextDirectionHeuristics.AnyStrong;
-import android.text.TextDirectionHeuristics.CharCount;
-import android.text.TextDirectionHeuristics.FirstStrong;
-import android.text.TextDirectionHeuristics.TextDirectionAlgorithm;
-import android.text.TextDirectionHeuristics.TextDirectionHeuristicImpl;
import android.text.TextPaint;
import android.text.TextUtils;
import android.text.TextWatcher;
@@ -88,6 +83,7 @@
import android.text.method.WordIterator;
import android.text.style.ClickableSpan;
import android.text.style.ParagraphStyle;
+import android.text.style.SpellCheckSpan;
import android.text.style.SuggestionSpan;
import android.text.style.TextAppearanceSpan;
import android.text.style.URLSpan;
@@ -220,7 +216,6 @@
* @attr ref android.R.styleable#TextView_imeActionLabel
* @attr ref android.R.styleable#TextView_imeActionId
* @attr ref android.R.styleable#TextView_editorExtras
- * @attr ref android.R.styleable#TextView_suggestionsEnabled
*/
@RemoteView
public class TextView extends View implements ViewTreeObserver.OnPreDrawListener {
@@ -334,7 +329,6 @@
private int mTextEditSuggestionItemLayout;
private SuggestionsPopupWindow mSuggestionsPopupWindow;
private SuggestionRangeSpan mSuggestionRangeSpan;
- private boolean mSuggestionsEnabled = true;
private int mCursorDrawableRes;
private final Drawable[] mCursorDrawable = new Drawable[2];
@@ -356,6 +350,8 @@
private WordIterator mWordIterator;
+ private SpellChecker mSpellChecker;
+
// The alignment to pass to Layout, or null if not resolved.
private Layout.Alignment mLayoutAlignment;
@@ -826,10 +822,6 @@
mTextIsSelectable = a.getBoolean(attr, false);
break;
- case com.android.internal.R.styleable.TextView_suggestionsEnabled:
- mSuggestionsEnabled = a.getBoolean(attr, true);
- break;
-
case com.android.internal.R.styleable.TextView_textAllCaps:
allCaps = a.getBoolean(attr, false);
break;
@@ -3100,18 +3092,19 @@
}
boolean needEditableForNotification = false;
+ boolean startSpellCheck = false;
if (mListeners != null && mListeners.size() != 0) {
needEditableForNotification = true;
}
- if (type == BufferType.EDITABLE || mInput != null ||
- needEditableForNotification) {
+ if (type == BufferType.EDITABLE || mInput != null || needEditableForNotification) {
Editable t = mEditableFactory.newEditable(text);
text = t;
setFilters(t, mFilters);
InputMethodManager imm = InputMethodManager.peekInstance();
if (imm != null) imm.restartInput(this);
+ startSpellCheck = true;
} else if (type == BufferType.SPANNABLE || mMovement != null) {
text = mSpannableFactory.newSpannable(text);
} else if (!(text instanceof CharWrapper)) {
@@ -3200,6 +3193,10 @@
sendOnTextChanged(text, 0, oldlen, textLength);
onTextChanged(text, 0, oldlen, textLength);
+ if (startSpellCheck) {
+ updateSpellCheckSpans(0, textLength);
+ }
+
if (needEditableForNotification) {
sendAfterTextChanged((Editable) text);
}
@@ -7113,8 +7110,9 @@
* to turn off ellipsizing.
*
* If {@link #setMaxLines} has been used to set two or more lines,
- * {@link TextUtils.TruncateAt#END} and {@link TextUtils.TruncateAt#MARQUEE}
- * are only supported (other ellipsizing types will not do anything).
+ * {@link android.text.TextUtils.TruncateAt#END} and
+ * {@link android.text.TextUtils.TruncateAt#MARQUEE}* are only supported
+ * (other ellipsizing types will not do anything).
*
* @attr ref android.R.styleable#TextView_ellipsize
*/
@@ -7376,7 +7374,7 @@
* @param lengthAfter The length of the replacement modified text
*/
protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) {
- // intentionally empty
+ // intentionally empty, template pattern method can be overridden by subclasses
}
/**
@@ -7388,6 +7386,9 @@
*/
protected void onSelectionChanged(int selStart, int selEnd) {
sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_TEXT_SELECTION_CHANGED);
+ if (mSpellChecker != null) {
+ mSpellChecker.onSelectionChanged();
+ }
}
/**
@@ -7422,8 +7423,7 @@
}
}
- private void sendBeforeTextChanged(CharSequence text, int start, int before,
- int after) {
+ private void sendBeforeTextChanged(CharSequence text, int start, int before, int after) {
if (mListeners != null) {
final ArrayList<TextWatcher> list = mListeners;
final int count = list.size();
@@ -7431,14 +7431,32 @@
list.get(i).beforeTextChanged(text, start, before, after);
}
}
+
+ // The spans that are inside or intersect the modified region no longer make sense
+ removeIntersectingSpans(start, start + before, SpellCheckSpan.class);
+ removeIntersectingSpans(start, start + before, SuggestionSpan.class);
+ }
+
+ // Removes all spans that are inside or actually overlap the start..end range
+ private <T> void removeIntersectingSpans(int start, int end, Class<T> type) {
+ if (!(mText instanceof Editable)) return;
+ Editable text = (Editable) mText;
+
+ T[] spans = text.getSpans(start, end, type);
+ final int length = spans.length;
+ for (int i = 0; i < length; i++) {
+ final int s = text.getSpanStart(spans[i]);
+ final int e = text.getSpanEnd(spans[i]);
+ if (e == start || s == end) break;
+ text.removeSpan(spans[i]);
+ }
}
/**
* Not private so it can be called from an inner class without going
* through a thunk.
*/
- void sendOnTextChanged(CharSequence text, int start, int before,
- int after) {
+ void sendOnTextChanged(CharSequence text, int start, int before, int after) {
if (mListeners != null) {
final ArrayList<TextWatcher> list = mListeners;
final int count = list.size();
@@ -7486,6 +7504,11 @@
sendOnTextChanged(buffer, start, before, after);
onTextChanged(buffer, start, before, after);
+ // The WordIterator text change listener may be called after this one.
+ // Make sure this changed text is rescanned before the iterator is used on it.
+ getWordIterator().forceUpdate();
+ updateSpellCheckSpans(start, start + after);
+
// Hide the controllers if the amount of content changed
if (before != after) {
hideControllers();
@@ -7573,7 +7596,7 @@
}
}
}
-
+
if (what instanceof ParcelableSpan) {
// If this is a span that can be sent to a remote process,
// the current extract editor would be interested in it.
@@ -7603,10 +7626,102 @@
}
}
}
+
+ if (what instanceof SpellCheckSpan) {
+ if (newStart < 0) {
+ getSpellChecker().removeSpellCheckSpan((SpellCheckSpan) what);
+ } else if (oldStart < 0) {
+ getSpellChecker().addSpellCheckSpan((SpellCheckSpan) what);
+ }
+ }
+
+ if (what instanceof SuggestionSpan) {
+ if (newStart < 0) {
+ Log.d("spellcheck", "REMOVE suggspan " + mText.subSequence(oldStart, oldEnd));
+ }
+ }
}
- private class ChangeWatcher
- implements TextWatcher, SpanWatcher {
+ /**
+ * Create new SpellCheckSpans on the modified region.
+ */
+ private void updateSpellCheckSpans(int start, int end) {
+ if (!(mText instanceof Editable) || !isSuggestionsEnabled()) return;
+ Editable text = (Editable) mText;
+
+ WordIterator wordIterator = getWordIterator();
+ wordIterator.setCharSequence(text);
+
+ // Move back to the beginning of the current word, if any
+ int wordStart = wordIterator.preceding(start);
+ int wordEnd;
+ if (wordStart == BreakIterator.DONE) {
+ wordEnd = wordIterator.following(start);
+ if (wordEnd != BreakIterator.DONE) {
+ wordStart = wordIterator.getBeginning(wordEnd);
+ }
+ } else {
+ wordEnd = wordIterator.getEnd(wordStart);
+ }
+ if (wordEnd == BreakIterator.DONE) {
+ return;
+ }
+
+ // Iterate over the newly added text and schedule new SpellCheckSpans
+ while (wordStart <= end) {
+ if (wordEnd >= start) {
+ // A word across the interval boundaries must remove boundary edition spans
+ if (wordStart < start && wordEnd > start) {
+ removeEditionSpansAt(start, text);
+ }
+
+ if (wordStart < end && wordEnd > end) {
+ removeEditionSpansAt(end, text);
+ }
+
+ // Do not create new boundary spans if they already exist
+ boolean createSpellCheckSpan = true;
+ if (wordEnd == start) {
+ SpellCheckSpan[] spellCheckSpans = text.getSpans(start, start,
+ SpellCheckSpan.class);
+ if (spellCheckSpans.length > 0) createSpellCheckSpan = false;
+ }
+
+ if (wordStart == end) {
+ SpellCheckSpan[] spellCheckSpans = text.getSpans(end, end,
+ SpellCheckSpan.class);
+ if (spellCheckSpans.length > 0) createSpellCheckSpan = false;
+ }
+
+ if (createSpellCheckSpan) {
+ text.setSpan(new SpellCheckSpan(), wordStart, wordEnd,
+ Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+ }
+ }
+
+ // iterate word by word
+ wordEnd = wordIterator.following(wordEnd);
+ if (wordEnd == BreakIterator.DONE) return;
+ wordStart = wordIterator.getBeginning(wordEnd);
+ if (wordStart == BreakIterator.DONE) {
+ Log.e(LOG_TAG, "Unable to find word beginning from " + wordEnd + "in " + mText);
+ return;
+ }
+ }
+ }
+
+ private static void removeEditionSpansAt(int offset, Editable text) {
+ SuggestionSpan[] suggestionSpans = text.getSpans(offset, offset, SuggestionSpan.class);
+ for (int i = 0; i < suggestionSpans.length; i++) {
+ text.removeSpan(suggestionSpans[i]);
+ }
+ SpellCheckSpan[] spellCheckSpans = text.getSpans(offset, offset, SpellCheckSpan.class);
+ for (int i = 0; i < spellCheckSpans.length; i++) {
+ text.removeSpan(spellCheckSpans[i]);
+ }
+ }
+
+ private class ChangeWatcher implements TextWatcher, SpanWatcher {
private CharSequence mBeforeText;
@@ -7631,8 +7746,7 @@
TextView.this.handleTextChanged(buffer, start, before, after);
if (AccessibilityManager.getInstance(mContext).isEnabled() &&
- (isFocused() || isSelected() &&
- isShown())) {
+ (isFocused() || isSelected() && isShown())) {
sendAccessibilityEventTypeViewTextChanged(mBeforeText, start, before, after);
mBeforeText = null;
}
@@ -7642,8 +7756,7 @@
if (DEBUG_EXTRACT) Log.v(LOG_TAG, "afterTextChanged: " + buffer);
TextView.this.sendAfterTextChanged(buffer);
- if (MetaKeyKeyListener.getMetaState(buffer,
- MetaKeyKeyListener.META_SELECTING) != 0) {
+ if (MetaKeyKeyListener.getMetaState(buffer, MetaKeyKeyListener.META_SELECTING) != 0) {
MetaKeyKeyListener.stopSelecting(TextView.this, buffer);
}
}
@@ -7841,17 +7954,20 @@
if (mInputContentType != null) {
mInputContentType.enterDown = false;
}
+
hideControllers();
- removeAllSuggestionSpans();
+
+ removeSpans(0, mText.length(), SuggestionSpan.class);
+ removeSpans(0, mText.length(), SpellCheckSpan.class);
}
startStopMarquee(hasWindowFocus);
}
- private void removeAllSuggestionSpans() {
+ private void removeSpans(int start, int end, Class<?> type) {
if (mText instanceof Editable) {
Editable editable = ((Editable) mText);
- SuggestionSpan[] spans = editable.getSpans(0, mText.length(), SuggestionSpan.class);
+ Object[] spans = editable.getSpans(start, end, type);
final int length = spans.length;
for (int i = 0; i < length; i++) {
editable.removeSpan(spans[i]);
@@ -7969,6 +8085,8 @@
}
}
}
+
+ handled = true;
}
if (handled) {
@@ -7980,11 +8098,22 @@
}
/**
+ * @return <code>true</code> if the cursor/current selection overlaps a {@link SuggestionSpan}.
+ */
+ private boolean isCursorInsideSuggestionSpan() {
+ if (!(mText instanceof Spannable)) return false;
+
+ SuggestionSpan[] suggestionSpans = ((Spannable) mText).getSpans(getSelectionStart(),
+ getSelectionEnd(), SuggestionSpan.class);
+ return (suggestionSpans.length > 0);
+ }
+
+ /**
* @return <code>true</code> if the cursor is inside an {@link SuggestionSpan} with
* {@link SuggestionSpan#FLAG_EASY_CORRECT} set.
*/
private boolean isCursorInsideEasyCorrectionSpan() {
- Spannable spannable = (Spannable) TextView.this.mText;
+ Spannable spannable = (Spannable) mText;
SuggestionSpan[] suggestionSpans = spannable.getSpans(getSelectionStart(),
getSelectionEnd(), SuggestionSpan.class);
for (int i = 0; i < suggestionSpans.length; i++) {
@@ -8445,16 +8574,14 @@
selectionStart = ((Spanned) mText).getSpanStart(url);
selectionEnd = ((Spanned) mText).getSpanEnd(url);
} else {
- if (mWordIterator == null) {
- mWordIterator = new WordIterator();
- }
- // WordIerator handles text changes, this is a no-op if text in unchanged.
- mWordIterator.setCharSequence(mText);
+ WordIterator wordIterator = getWordIterator();
+ // WordIterator handles text changes, this is a no-op if text in unchanged.
+ wordIterator.setCharSequence(mText);
- selectionStart = mWordIterator.getBeginning(minOffset);
+ selectionStart = wordIterator.getBeginning(minOffset);
if (selectionStart == BreakIterator.DONE) return false;
- selectionEnd = mWordIterator.getEnd(maxOffset);
+ selectionEnd = wordIterator.getEnd(maxOffset);
if (selectionEnd == BreakIterator.DONE) return false;
}
@@ -8462,6 +8589,20 @@
return true;
}
+ WordIterator getWordIterator() {
+ if (mWordIterator == null) {
+ mWordIterator = new WordIterator();
+ }
+ return mWordIterator;
+ }
+
+ private SpellChecker getSpellChecker() {
+ if (mSpellChecker == null) {
+ mSpellChecker = new SpellChecker(this);
+ }
+ return mSpellChecker;
+ }
+
private long getLastTouchOffsets() {
int minOffset, maxOffset;
@@ -8790,7 +8931,7 @@
final int offset = getOffsetForPosition(mLastDownPositionX, mLastDownPositionY);
stopSelectionActionMode();
Selection.setSelection((Spannable) mText, offset);
- getInsertionController().showImmediately();
+ getInsertionController().showWithActionPopup();
handled = true;
}
@@ -9067,10 +9208,12 @@
}
private class SuggestionsPopupWindow extends PinnedPopupWindow implements OnClickListener {
- private static final int MAX_NUMBER_SUGGESTIONS = 5;
+ private static final int MAX_NUMBER_SUGGESTIONS = SuggestionSpan.SUGGESTIONS_MAX_SIZE;
private static final int NO_SUGGESTIONS = -1;
+ private static final float AVERAGE_HIGHLIGHTS_PER_SUGGESTION = 1.4f;
private WordIterator mSuggestionWordIterator;
- private TextAppearanceSpan[] mHighlightSpans = new TextAppearanceSpan[0];
+ private TextAppearanceSpan[] mHighlightSpans = new TextAppearanceSpan
+ [(int) (AVERAGE_HIGHLIGHTS_PER_SUGGESTION * MAX_NUMBER_SUGGESTIONS)];
@Override
protected void createPopupWindow() {
@@ -9149,9 +9292,10 @@
@Override
public void show() {
if (!(mText instanceof Editable)) return;
- updateSuggestions();
- super.show();
+ if (updateSuggestions()) {
+ super.show();
+ }
}
@Override
@@ -9179,7 +9323,7 @@
}
}
- private void updateSuggestions() {
+ private boolean updateSuggestions() {
Spannable spannable = (Spannable)TextView.this.mText;
SuggestionSpan[] suggestionSpans = getSuggestionSpans();
@@ -9217,22 +9361,15 @@
}
}
- if (totalNbSuggestions == 0) {
- // TODO Replace by final text, use a dedicated layout, add a fade out timer...
- TextView textView = (TextView) mContentView.getChildAt(0);
- textView.setText("No suggestions available");
- SuggestionInfo suggestionInfo = (SuggestionInfo) textView.getTag();
- suggestionInfo.spanStart = NO_SUGGESTIONS;
- totalNbSuggestions++;
- } else {
- if (mSuggestionRangeSpan == null) mSuggestionRangeSpan = new SuggestionRangeSpan();
- ((Editable) mText).setSpan(mSuggestionRangeSpan, spanUnionStart, spanUnionEnd,
- Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+ if (totalNbSuggestions == 0) return false;
- for (int i = 0; i < totalNbSuggestions; i++) {
- final TextView textView = (TextView) mContentView.getChildAt(i);
- highlightTextDifferences(textView, spanUnionStart, spanUnionEnd);
- }
+ if (mSuggestionRangeSpan == null) mSuggestionRangeSpan = new SuggestionRangeSpan();
+ ((Editable) mText).setSpan(mSuggestionRangeSpan, spanUnionStart, spanUnionEnd,
+ Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+
+ for (int i = 0; i < totalNbSuggestions; i++) {
+ final TextView textView = (TextView) mContentView.getChildAt(i);
+ highlightTextDifferences(textView, spanUnionStart, spanUnionEnd);
}
for (int i = 0; i < totalNbSuggestions; i++) {
@@ -9241,6 +9378,27 @@
for (int i = totalNbSuggestions; i < MAX_NUMBER_SUGGESTIONS; i++) {
mContentView.getChildAt(i).setVisibility(GONE);
}
+
+ return true;
+ }
+
+ private void onDictionarySuggestionsReceived(String[] suggestions) {
+ if (suggestions.length == 0) {
+ // TODO Actual implementation of this feature
+ suggestions = new String[] {"Add to dictionary"};
+ }
+
+ WordIterator wordIterator = getWordIterator();
+ wordIterator.setCharSequence(mText);
+
+ final int pos = getSelectionStart();
+ int wordStart = wordIterator.getBeginning(pos);
+ int wordEnd = wordIterator.getEnd(pos);
+
+ SuggestionSpan suggestionSpan = new SuggestionSpan(getContext(), suggestions, 0);
+ ((Editable) mText).setSpan(suggestionSpan, wordStart, wordEnd,
+ Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+ show();
}
private long[] getWordLimits(CharSequence text) {
@@ -9422,6 +9580,15 @@
final String originalText = mText.subSequence(spanStart, spanEnd).toString();
((Editable) mText).replace(spanStart, spanEnd, suggestion);
+ // A replacement on a misspelled text removes the misspelled flag.
+ // TODO restore the flag if the misspelled word is selected back?
+ int suggestionSpanFlags = suggestionInfo.suggestionSpan.getFlags();
+ if ((suggestionSpanFlags & SuggestionSpan.FLAG_MISSPELLED) > 0) {
+ suggestionSpanFlags &= ~(SuggestionSpan.FLAG_MISSPELLED);
+ suggestionSpanFlags &= ~(SuggestionSpan.FLAG_EASY_CORRECT);
+ suggestionInfo.suggestionSpan.setFlags(suggestionSpanFlags);
+ }
+
// Notify source IME of the suggestion pick. Do this before swaping texts.
if (!TextUtils.isEmpty(
suggestionInfo.suggestionSpan.getNotificationTargetClassName())) {
@@ -9471,53 +9638,46 @@
boolean areSuggestionsShown() {
return mSuggestionsPopupWindow != null && mSuggestionsPopupWindow.isShowing();
- }
+ }
+
+ void onDictionarySuggestionsReceived(String[] suggestions) {
+ if (mSuggestionsPopupWindow != null) {
+ mSuggestionsPopupWindow.onDictionarySuggestionsReceived(suggestions);
+ }
+ }
/**
- * Some parts of the text can have alternate suggestion text attached. This is typically done by
- * the IME by adding {@link SuggestionSpan}s to the text.
+ * Return whether or not suggestions are enabled on this TextView. The suggestions are generated
+ * by the IME or by the spell checker as the user types. This is done by adding
+ * {@link SuggestionSpan}s to the text.
*
* When suggestions are enabled (default), this list of suggestions will be displayed when the
- * user double taps on these parts of the text. No suggestions are displayed when this value is
- * false. Use {@link #setSuggestionsEnabled(boolean)} to change this value.
+ * user asks for them on these parts of the text. This value depends on the inputType of this
+ * TextView.
*
- * Note that suggestions are only enabled for a subset of input types. In addition to setting
- * this flag to <code>true</code> using {@link #setSuggestionsEnabled(boolean)} or the
- * <code>android:suggestionsEnabled</code> xml attribute, this method will return
- * <code>true</code> only if the class of your input type is {@link InputType#TYPE_CLASS_TEXT}.
- * In addition, the type variation must also be one of
+ * The class of the input type must be {@link InputType#TYPE_CLASS_TEXT}.
+ *
+ * In addition, the type variation must be one of
* {@link InputType#TYPE_TEXT_VARIATION_NORMAL},
* {@link InputType#TYPE_TEXT_VARIATION_EMAIL_SUBJECT},
* {@link InputType#TYPE_TEXT_VARIATION_LONG_MESSAGE},
* {@link InputType#TYPE_TEXT_VARIATION_SHORT_MESSAGE} or
* {@link InputType#TYPE_TEXT_VARIATION_WEB_EDIT_TEXT}.
*
- * @return true if the suggestions popup window is enabled.
+ * And finally, the {@link InputType#TYPE_TEXT_FLAG_NO_SUGGESTIONS} flag must <i>not</i> be set.
*
- * @attr ref android.R.styleable#TextView_suggestionsEnabled
+ * @return true if the suggestions popup window is enabled, based on the inputType.
*/
public boolean isSuggestionsEnabled() {
- if (!mSuggestionsEnabled) return false;
if ((mInputType & InputType.TYPE_MASK_CLASS) != InputType.TYPE_CLASS_TEXT) return false;
+ if ((mInputType & InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS) > 0) return false;
+
final int variation = mInputType & EditorInfo.TYPE_MASK_VARIATION;
- if (variation == EditorInfo.TYPE_TEXT_VARIATION_NORMAL ||
+ return (variation == EditorInfo.TYPE_TEXT_VARIATION_NORMAL ||
variation == EditorInfo.TYPE_TEXT_VARIATION_EMAIL_SUBJECT ||
variation == EditorInfo.TYPE_TEXT_VARIATION_LONG_MESSAGE ||
variation == EditorInfo.TYPE_TEXT_VARIATION_SHORT_MESSAGE ||
- variation == EditorInfo.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT) return true;
-
- return false;
- }
-
- /**
- * Enables or disables the suggestion popup. See {@link #isSuggestionsEnabled()}.
- *
- * @param enabled Whether or not suggestions are enabled.
- *
- * @attr ref android.R.styleable#TextView_suggestionsEnabled
- */
- public void setSuggestionsEnabled(boolean enabled) {
- mSuggestionsEnabled = enabled;
+ variation == EditorInfo.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT);
}
/**
@@ -9787,11 +9947,11 @@
@Override
public void show() {
boolean canPaste = canPaste();
- boolean suggestionsEnabled = isSuggestionsEnabled();
+ boolean canSuggest = isSuggestionsEnabled() && isCursorInsideSuggestionSpan();
mPasteTextView.setVisibility(canPaste ? View.VISIBLE : View.GONE);
- mReplaceTextView.setVisibility(suggestionsEnabled ? View.VISIBLE : View.GONE);
+ mReplaceTextView.setVisibility(canSuggest ? View.VISIBLE : View.GONE);
- if (!canPaste && !suggestionsEnabled) return;
+ if (!canPaste && !canSuggest) return;
super.show();
}
@@ -9802,6 +9962,9 @@
onTextContextMenuItem(ID_PASTE);
hide();
} else if (view == mReplaceTextView) {
+ final int middle = (getSelectionStart() + getSelectionEnd()) / 2;
+ stopSelectionActionMode();
+ Selection.setSelection((Spannable) mText, middle);
showSuggestions();
}
}
@@ -10133,17 +10296,18 @@
@Override
public void show() {
super.show();
- hideAfterDelay();
- }
-
- public void show(int delayBeforeShowActionPopup) {
- show();
final long durationSinceCutOrCopy = SystemClock.uptimeMillis() - sLastCutOrCopyTime;
if (durationSinceCutOrCopy < RECENT_CUT_COPY_DURATION) {
- delayBeforeShowActionPopup = 0;
+ showActionPopupWindow(0);
}
- showActionPopupWindow(delayBeforeShowActionPopup);
+
+ hideAfterDelay();
+ }
+
+ public void showWithActionPopup() {
+ show();
+ showActionPopupWindow(0);
}
private void hideAfterDelay() {
@@ -10194,7 +10358,7 @@
// Tapping on the handle dismisses the displayed action popup
mActionPopupWindow.hide();
} else {
- show(0);
+ showWithActionPopup();
}
}
}
@@ -10349,16 +10513,14 @@
}
private class InsertionPointCursorController implements CursorController {
- private static final int DELAY_BEFORE_PASTE_ACTION = 1600;
-
private InsertionHandleView mHandle;
public void show() {
- getHandle().show(DELAY_BEFORE_PASTE_ACTION);
+ getHandle().show();
}
- public void showImmediately() {
- getHandle().show(0);
+ public void showWithActionPopup() {
+ getHandle().showWithActionPopup();
}
public void hide() {
@@ -10390,7 +10552,7 @@
}
private class SelectionModifierCursorController implements CursorController {
- private static final int DELAY_BEFORE_REPLACE_ACTION = 1200;
+ private static final int DELAY_BEFORE_REPLACE_ACTION = 200; // milliseconds
// The cursor controller handles, lazily created when shown.
private SelectionStartHandleView mStartHandle;
private SelectionEndHandleView mEndHandle;
@@ -10879,8 +11041,8 @@
private int mAutoLinkMask;
private boolean mLinksClickable = true;
- private float mSpacingMult = 1;
- private float mSpacingAdd = 0;
+ private float mSpacingMult = 1.0f;
+ private float mSpacingAdd = 0.0f;
private boolean mTextIsSelectable = false;
private static final int LINES = 1;
diff --git a/core/java/com/android/internal/textservice/ITextServicesManager.aidl b/core/java/com/android/internal/textservice/ITextServicesManager.aidl
index cc30c176..b18af02 100644
--- a/core/java/com/android/internal/textservice/ITextServicesManager.aidl
+++ b/core/java/com/android/internal/textservice/ITextServicesManager.aidl
@@ -37,5 +37,7 @@
oneway void finishSpellCheckerService(in ISpellCheckerSessionListener listener);
oneway void setCurrentSpellChecker(String locale, String sciId);
oneway void setCurrentSpellCheckerSubtype(String locale, int hashCode);
+ oneway void setSpellCheckerEnabled(boolean enabled);
+ boolean isSpellCheckerEnabled();
SpellCheckerInfo[] getEnabledSpellCheckers();
}
diff --git a/core/java/com/android/internal/view/menu/ActionMenuView.java b/core/java/com/android/internal/view/menu/ActionMenuView.java
index d613921..b355c41 100644
--- a/core/java/com/android/internal/view/menu/ActionMenuView.java
+++ b/core/java/com/android/internal/view/menu/ActionMenuView.java
@@ -31,6 +31,7 @@
private static final String TAG = "ActionMenuView";
static final int MIN_CELL_SIZE = 56; // dips
+ static final int GENERATED_ITEM_PADDING = 4; // dips
private MenuBuilder mMenu;
@@ -39,6 +40,7 @@
private boolean mFormatItems;
private int mFormatItemsWidth;
private int mMinCellSize;
+ private int mGeneratedItemPadding;
private int mMeasuredExtraWidth;
public ActionMenuView(Context context) {
@@ -48,7 +50,9 @@
public ActionMenuView(Context context, AttributeSet attrs) {
super(context, attrs);
setBaselineAligned(false);
- mMinCellSize = (int) (MIN_CELL_SIZE * context.getResources().getDisplayMetrics().density);
+ final float density = context.getResources().getDisplayMetrics().density;
+ mMinCellSize = (int) (MIN_CELL_SIZE * density);
+ mGeneratedItemPadding = (int) (GENERATED_ITEM_PADDING * density);
}
public void setPresenter(ActionMenuPresenter presenter) {
@@ -133,8 +137,15 @@
final View child = getChildAt(i);
if (child.getVisibility() == GONE) continue;
+ final boolean isGeneratedItem = child instanceof ActionMenuItemView;
visibleItemCount++;
+ if (isGeneratedItem) {
+ // Reset padding for generated menu item views; it may change below
+ // and views are recycled.
+ child.setPadding(mGeneratedItemPadding, 0, mGeneratedItemPadding, 0);
+ }
+
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
lp.expanded = false;
lp.extraPixels = 0;
@@ -142,6 +153,7 @@
lp.expandable = false;
lp.leftMargin = 0;
lp.rightMargin = 0;
+ lp.preventEdgeOffset = isGeneratedItem && ((ActionMenuItemView) child).hasText();
// Overflow always gets 1 cell. No more, no less.
final int cellsAvailable = lp.isOverflowButton ? 1 : cellsRemaining;
@@ -158,6 +170,10 @@
if (cellsUsed == 1) smallestItemsAt |= (1 << i);
}
+ // When we have overflow and a single expanded (text) item, we want to try centering it
+ // visually in the available space even though overflow consumes some of it.
+ final boolean centerSingleExpandedItem = hasOverflow && visibleItemCount == 2;
+
// Divide space for remaining cells if we have items that can expand.
// Try distributing whole leftover cells to smaller items first.
@@ -184,16 +200,27 @@
}
}
- if (minCellsItemCount > cellsRemaining) break; // Couldn't expand anything evenly. Stop.
-
// Items that get expanded will always be in the set of smallest items when we're done.
smallestItemsAt |= minCellsAt;
- for (int i = 0; i < childCount; i++) {
- if ((minCellsAt & (1 << i)) == 0) continue;
+ if (minCellsItemCount > cellsRemaining) break; // Couldn't expand anything evenly. Stop.
+ // We have enough cells, all minimum size items will be incremented.
+ minCells++;
+
+ for (int i = 0; i < childCount; i++) {
final View child = getChildAt(i);
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+ if ((minCellsAt & (1 << i)) == 0) {
+ // If this item is already at our small item count, mark it for later.
+ if (lp.cellsUsed == minCells) smallestItemsAt |= 1 << i;
+ continue;
+ }
+
+ if (centerSingleExpandedItem && lp.preventEdgeOffset && cellsRemaining == 1) {
+ // Add padding to this item such that it centers.
+ child.setPadding(mGeneratedItemPadding + cellSize, 0, mGeneratedItemPadding, 0);
+ }
lp.cellsUsed++;
lp.expanded = true;
cellsRemaining--;
@@ -207,16 +234,18 @@
final boolean singleItem = !hasOverflow && visibleItemCount == 1;
if (cellsRemaining > 0 && smallestItemsAt != 0 &&
- (cellsRemaining < visibleItemCount - 1 || singleItem)) {
+ (cellsRemaining < visibleItemCount - 1 || singleItem || maxCellsUsed > 1)) {
float expandCount = Long.bitCount(smallestItemsAt);
if (!singleItem) {
// The items at the far edges may only expand by half in order to pin to either side.
if ((smallestItemsAt & 1) != 0) {
- expandCount -= 0.5f;
+ LayoutParams lp = (LayoutParams) getChildAt(0).getLayoutParams();
+ if (!lp.preventEdgeOffset) expandCount -= 0.5f;
}
if ((smallestItemsAt & (1 << (childCount - 1))) != 0) {
- expandCount -= 0.5f;
+ LayoutParams lp = ((LayoutParams) getChildAt(childCount - 1).getLayoutParams());
+ if (!lp.preventEdgeOffset) expandCount -= 0.5f;
}
}
@@ -232,7 +261,7 @@
// If this is one of our views, expand and measure at the larger size.
lp.extraPixels = extraPixels;
lp.expanded = true;
- if (i == 0) {
+ if (i == 0 && !lp.preventEdgeOffset) {
// First item gets part of its new padding pushed out of sight.
// The last item will get this implicitly from layout.
lp.leftMargin = -extraPixels / 2;
@@ -496,6 +525,8 @@
public int extraPixels;
@ViewDebug.ExportedProperty(category = "layout")
public boolean expandable;
+ @ViewDebug.ExportedProperty(category = "layout")
+ public boolean preventEdgeOffset;
public boolean expanded;
diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp
index 6b5ca50..b8f2d6f 100644
--- a/core/jni/android_util_Binder.cpp
+++ b/core/jni/android_util_Binder.cpp
@@ -39,8 +39,6 @@
#include <binder/IServiceManager.h>
#include <utils/threads.h>
-#include <ScopedUtfChars.h>
-
#include <android_runtime/AndroidRuntime.h>
//#undef LOGV
@@ -446,25 +444,6 @@
return result;
}
- void warnIfStillLive() {
- JNIEnv* env = javavm_to_jnienv(mVM);
- if (mObject != NULL) {
- // Okay, something is wrong -- we have a hard reference to a live death
- // recipient on the VM side, but the list is being torn down.
- jclass clazz = env->GetObjectClass(mObject);
- jmethodID getnameMethod = env->GetMethodID(clazz, "getName", NULL);
- jstring nameString = (jstring) env->CallObjectMethod(clazz, getnameMethod);
- if (nameString) {
- ScopedUtfChars nameUtf(env, nameString);
- LOGW("BinderProxy is being destroyed but the application did not call "
- "unlinkToDeath to unlink all of its death recipients beforehand. "
- "Releasing leaked death recipient: %s", nameUtf.c_str());
- env->DeleteLocalRef(nameString);
- }
- env->DeleteLocalRef(clazz);
- }
- }
-
protected:
virtual ~JavaDeathRecipient()
{
@@ -499,10 +478,7 @@
// to the list are holding references on the list object. Only when they are torn
// down can the list header be destroyed.
if (mList.size() > 0) {
- List< sp<JavaDeathRecipient> >::iterator iter;
- for (iter = mList.begin(); iter != mList.end(); iter++) {
- (*iter)->warnIfStillLive();
- }
+ LOGE("Retiring DRL %p with extant death recipients\n", this);
}
}
diff --git a/core/res/res/drawable-hdpi/ic_menu_selectall_holo_dark.png b/core/res/res/drawable-hdpi/ic_menu_selectall_holo_dark.png
index 5579443..b161361 100644
--- a/core/res/res/drawable-hdpi/ic_menu_selectall_holo_dark.png
+++ b/core/res/res/drawable-hdpi/ic_menu_selectall_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_menu_selectall_holo_light.png b/core/res/res/drawable-hdpi/ic_menu_selectall_holo_light.png
index 6674914..0a7b364 100644
--- a/core/res/res/drawable-hdpi/ic_menu_selectall_holo_light.png
+++ b/core/res/res/drawable-hdpi/ic_menu_selectall_holo_light.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 2af7e81..b59b492 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 20fc20a..57b8b31 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 74ce1ee..14d26a5 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 82b5671..e457a66 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 7220c2f..86c036d 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 5648af0..ddd3e74 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 633df1b..74e7e2e 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 1efa5eb..989a18c 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-mdpi/spinner_16_inner_holo.png b/core/res/res/drawable-mdpi/spinner_16_inner_holo.png
index 4f6f981..c0f1b20 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 07df4cb..0492a62 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 fab8766..5e141d8 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 f345311..07ba3f3 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 91a29fd..8c27069 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 024f0f2..d5f0490 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 a388434..3e263e8 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 e81bb06..6eb6d10 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-xhdpi/spinner_16_inner_holo.png b/core/res/res/drawable-xhdpi/spinner_16_inner_holo.png
index 8f2b8ae..7294519 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 583e4a2..d43da4e 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 b202d4e..eecac27 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 34fbbf0..eb91b2c 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 c2df6b4..b1b8232 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 fd202f4..0c15e12 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 9f2044d..6215e95 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 a416478..0a67fff 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/layout/keyguard_screen_password_landscape.xml b/core/res/res/layout/keyguard_screen_password_landscape.xml
index bc86ab7..12df99e 100644
--- a/core/res/res/layout/keyguard_screen_password_landscape.xml
+++ b/core/res/res/layout/keyguard_screen_password_landscape.xml
@@ -151,7 +151,6 @@
android:background="@drawable/lockscreen_password_field_dark"
android:textColor="?android:attr/textColorPrimary"
android:imeOptions="flagNoFullscreen|actionDone"
- android:suggestionsEnabled="false"
/>
<ImageView android:id="@+id/switch_ime_button"
diff --git a/core/res/res/layout/keyguard_screen_password_portrait.xml b/core/res/res/layout/keyguard_screen_password_portrait.xml
index 994c439..6145e47 100644
--- a/core/res/res/layout/keyguard_screen_password_portrait.xml
+++ b/core/res/res/layout/keyguard_screen_password_portrait.xml
@@ -114,7 +114,7 @@
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="#ffffffff"
android:imeOptions="actionDone"
- android:suggestionsEnabled="false"/>
+ />
<ImageView android:id="@+id/switch_ime_button"
android:layout_width="wrap_content"
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index bb61c72..a536961 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -881,10 +881,6 @@
Default value is false. EditText content is always selectable. -->
<attr name="textIsSelectable" format="boolean" />
- <!-- When true, IME suggestions will be displayed when the user double taps on editable text.
- The default value is true. -->
- <attr name="suggestionsEnabled" format="boolean" />
-
<!-- Where to ellipsize text. -->
<attr name="ellipsize">
<enum name="none" value="0" />
@@ -3148,8 +3144,6 @@
<!-- Indicates that the content of a non-editable text can be selected. -->
<attr name="textIsSelectable" />
- <!-- Suggestions will be displayed when the user double taps on editable text. -->
- <attr name="suggestionsEnabled" />
<!-- Present the text in ALL CAPS. This may use a small-caps form when available. -->
<attr name="textAllCaps" />
</declare-styleable>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index a6bf1e0..b9d05fd 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1717,8 +1717,6 @@
<public type="attr" name="textSuggestionsWindowStyle" />
<public type="attr" name="textEditSuggestionItemLayout" />
- <public type="attr" name="suggestionsEnabled" />
-
<public type="attr" name="rowCount" />
<public type="attr" name="rowOrderPreserved" />
<public type="attr" name="columnCount" />
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 8eaac8c..9455124 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -2470,7 +2470,7 @@
<string name="paste">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>
+ <string name="replace">Replace\u2026</string>
<!-- Item on EditText context menu. This action is used to copy a URL from the edit field into the clipboard. -->
<string name="copyUrl">Copy URL</string>
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 94c6e41..d8d613a 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -1854,7 +1854,7 @@
<style name="Widget.Holo.ActionButton.Overflow">
<item name="android:src">@android:drawable/ic_menu_moreoverflow_holo_dark</item>
- <item name="android:background">?android:attr/selectableItemBackground</item>
+ <item name="android:background">?android:attr/actionBarItemBackground</item>
<item name="android:contentDescription">@string/action_menu_overflow_description</item>
</style>
diff --git a/core/tests/coretests/res/layout/interrogation_activity.xml b/core/tests/coretests/res/layout/interrogation_activity.xml
index 28d965b..44ed75c 100644
--- a/core/tests/coretests/res/layout/interrogation_activity.xml
+++ b/core/tests/coretests/res/layout/interrogation_activity.xml
@@ -30,20 +30,20 @@
>
<Button
android:id="@+id/button1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ android:layout_width="160px"
+ android:layout_height="100px"
android:text="@string/button1"
/>
<Button
android:id="@+id/button2"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ android:layout_width="160px"
+ android:layout_height="100px"
android:text="@string/button2"
/>
<Button
android:id="@+id/button3"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ android:layout_width="160px"
+ android:layout_height="100px"
android:text="@string/button3"
/>
</LinearLayout>
@@ -55,20 +55,20 @@
>
<Button
android:id="@+id/button4"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ android:layout_width="160px"
+ android:layout_height="100px"
android:text="@string/button4"
/>
<Button
android:id="@+id/button5"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ android:layout_width="160px"
+ android:layout_height="100px"
android:text="@string/button5"
/>
<Button
android:id="@+id/button6"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ android:layout_width="160px"
+ android:layout_height="100px"
android:text="@string/button6"
/>
</LinearLayout>
@@ -80,20 +80,20 @@
>
<Button
android:id="@+id/button7"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ android:layout_width="160px"
+ android:layout_height="100px"
android:text="@string/button7"
/>
<Button
android:id="@+id/button8"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ android:layout_width="160px"
+ android:layout_height="100px"
android:text="@string/button8"
/>
<Button
android:id="@+id/button9"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ android:layout_width="160px"
+ android:layout_height="100px"
android:text="@string/button9"
/>
</LinearLayout>
diff --git a/core/tests/coretests/src/android/accessibilityservice/InterrogationActivityTest.java b/core/tests/coretests/src/android/accessibilityservice/InterrogationActivityTest.java
index 99d534c..a542a1b 100644
--- a/core/tests/coretests/src/android/accessibilityservice/InterrogationActivityTest.java
+++ b/core/tests/coretests/src/android/accessibilityservice/InterrogationActivityTest.java
@@ -31,6 +31,7 @@
import android.test.suitebuilder.annotation.LargeTest;
import android.util.Log;
import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityInteractionClient;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.IAccessibilityManager;
@@ -81,8 +82,8 @@
// bring up the activity
getActivity();
- AccessibilityNodeInfo button =
- getConnection().findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.button5);
+ AccessibilityNodeInfo button = AccessibilityInteractionClient.getInstance()
+ .findAccessibilityNodeInfoByViewIdInActiveWindow(getConnection(), R.id.button5);
assertNotNull(button);
assertEquals(0, button.getChildCount());
@@ -91,8 +92,8 @@
button.getBoundsInParent(bounds);
assertEquals(0, bounds.left);
assertEquals(0, bounds.top);
- assertEquals(73, bounds.right);
- assertEquals(48, bounds.bottom);
+ assertEquals(160, bounds.right);
+ assertEquals(100, bounds.bottom);
// char sequence attributes
assertEquals("com.android.frameworks.coretests", button.getPackageName());
@@ -133,8 +134,8 @@
getActivity();
// find a view by text
- List<AccessibilityNodeInfo> buttons =
- getConnection().findAccessibilityNodeInfosByViewTextInActiveWindow("butto");
+ List<AccessibilityNodeInfo> buttons = AccessibilityInteractionClient.getInstance()
+ .findAccessibilityNodeInfosByViewTextInActiveWindow(getConnection(), "butto");
assertEquals(9, buttons.size());
} finally {
afterClassIfNeeded();
@@ -170,8 +171,8 @@
classNameAndTextList.add("android.widget.ButtonButton8");
classNameAndTextList.add("android.widget.ButtonButton9");
- AccessibilityNodeInfo root =
- getConnection().findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.root);
+ AccessibilityNodeInfo root = AccessibilityInteractionClient.getInstance()
+ .findAccessibilityNodeInfoByViewIdInActiveWindow(getConnection(), R.id.root);
assertNotNull("We must find the existing root.", root);
Queue<AccessibilityNodeInfo> fringe = new LinkedList<AccessibilityNodeInfo>();
@@ -214,15 +215,16 @@
getActivity();
// find a view and make sure it is not focused
- AccessibilityNodeInfo button =
- getConnection().findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.button5);
+ AccessibilityNodeInfo button = AccessibilityInteractionClient.getInstance()
+ .findAccessibilityNodeInfoByViewIdInActiveWindow(getConnection(), R.id.button5);
assertFalse(button.isFocused());
// focus the view
assertTrue(button.performAction(ACTION_FOCUS));
// find the view again and make sure it is focused
- button = getConnection().findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.button5);
+ button = AccessibilityInteractionClient.getInstance()
+ .findAccessibilityNodeInfoByViewIdInActiveWindow(getConnection(), R.id.button5);
assertTrue(button.isFocused());
} finally {
afterClassIfNeeded();
@@ -242,22 +244,24 @@
getActivity();
// find a view and make sure it is not focused
- AccessibilityNodeInfo button =
- getConnection().findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.button5);
+ AccessibilityNodeInfo button = AccessibilityInteractionClient.getInstance()
+ .findAccessibilityNodeInfoByViewIdInActiveWindow(getConnection(), R.id.button5);
assertFalse(button.isFocused());
// focus the view
assertTrue(button.performAction(ACTION_FOCUS));
// find the view again and make sure it is focused
- button = getConnection().findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.button5);
+ button = AccessibilityInteractionClient.getInstance()
+ .findAccessibilityNodeInfoByViewIdInActiveWindow(getConnection(), R.id.button5);
assertTrue(button.isFocused());
// unfocus the view
assertTrue(button.performAction(ACTION_CLEAR_FOCUS));
// find the view again and make sure it is not focused
- button = getConnection().findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.button5);
+ button = AccessibilityInteractionClient.getInstance()
+ .findAccessibilityNodeInfoByViewIdInActiveWindow(getConnection(), R.id.button5);
assertFalse(button.isFocused());
} finally {
afterClassIfNeeded();
@@ -278,15 +282,16 @@
getActivity();
// find a view and make sure it is not selected
- AccessibilityNodeInfo button =
- getConnection().findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.button5);
+ AccessibilityNodeInfo button = AccessibilityInteractionClient.getInstance()
+ .findAccessibilityNodeInfoByViewIdInActiveWindow(getConnection(), R.id.button5);
assertFalse(button.isSelected());
// select the view
assertTrue(button.performAction(ACTION_SELECT));
// find the view again and make sure it is selected
- button = getConnection().findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.button5);
+ button = AccessibilityInteractionClient.getInstance()
+ .findAccessibilityNodeInfoByViewIdInActiveWindow(getConnection(), R.id.button5);
assertTrue(button.isSelected());
} finally {
afterClassIfNeeded();
@@ -306,22 +311,24 @@
getActivity();
// find a view and make sure it is not selected
- AccessibilityNodeInfo button =
- getConnection().findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.button5);
+ AccessibilityNodeInfo button = AccessibilityInteractionClient.getInstance()
+ .findAccessibilityNodeInfoByViewIdInActiveWindow(getConnection(), R.id.button5);
assertFalse(button.isSelected());
// select the view
assertTrue(button.performAction(ACTION_SELECT));
// find the view again and make sure it is selected
- button = getConnection().findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.button5);
+ button = AccessibilityInteractionClient.getInstance()
+ .findAccessibilityNodeInfoByViewIdInActiveWindow(getConnection(), R.id.button5);
assertTrue(button.isSelected());
// unselect the view
assertTrue(button.performAction(ACTION_CLEAR_SELECTION));
// find the view again and make sure it is not selected
- button = getConnection().findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.button5);
+ button = AccessibilityInteractionClient.getInstance()
+ .findAccessibilityNodeInfoByViewIdInActiveWindow(getConnection(), R.id.button5);
assertFalse(button.isSelected());
} finally {
afterClassIfNeeded();
@@ -342,8 +349,8 @@
getActivity();
// find a view and make sure it is not focused
- AccessibilityNodeInfo button =
- getConnection().findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.button5);
+ AccessibilityNodeInfo button = AccessibilityInteractionClient.getInstance()
+ .findAccessibilityNodeInfoByViewIdInActiveWindow(getConnection(), R.id.button5);
assertFalse(button.isSelected());
// focus the view
@@ -406,8 +413,8 @@
getActivity();
// find a view and make sure it is not focused
- AccessibilityNodeInfo button =
- getConnection().findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.button5);
+ AccessibilityNodeInfo button = AccessibilityInteractionClient.getInstance()
+ .findAccessibilityNodeInfoByViewIdInActiveWindow(getConnection(), R.id.button5);
AccessibilityNodeInfo parent = button.getParent();
final int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
diff --git a/core/tests/coretests/src/android/net/NetworkStatsHistoryTest.java b/core/tests/coretests/src/android/net/NetworkStatsHistoryTest.java
index 4db4ea5..b888d9a 100644
--- a/core/tests/coretests/src/android/net/NetworkStatsHistoryTest.java
+++ b/core/tests/coretests/src/android/net/NetworkStatsHistoryTest.java
@@ -99,7 +99,7 @@
new NetworkStats.Entry(1024L, 10L, 2048L, 20L, 2L));
assertEquals(1, stats.size());
- assertValues(stats, 0, 1024L, 10L, 2048L, 20L, 2L);
+ assertValues(stats, 0, SECOND_IN_MILLIS, 1024L, 10L, 2048L, 20L, 2L);
}
public void testRecordEqualBuckets() throws Exception {
@@ -112,8 +112,8 @@
new NetworkStats.Entry(1024L, 10L, 128L, 2L, 2L));
assertEquals(2, stats.size());
- assertValues(stats, 0, 512L, 5L, 64L, 1L, 1L);
- assertValues(stats, 1, 512L, 5L, 64L, 1L, 1L);
+ assertValues(stats, 0, HOUR_IN_MILLIS / 2, 512L, 5L, 64L, 1L, 1L);
+ assertValues(stats, 1, HOUR_IN_MILLIS / 2, 512L, 5L, 64L, 1L, 1L);
}
public void testRecordTouchingBuckets() throws Exception {
@@ -129,11 +129,11 @@
assertEquals(3, stats.size());
// first bucket should have (1/20 of value)
- assertValues(stats, 0, 50L, 100L, 250L, 500L, 5L);
+ assertValues(stats, 0, MINUTE_IN_MILLIS, 50L, 100L, 250L, 500L, 5L);
// second bucket should have (15/20 of value)
- assertValues(stats, 1, 750L, 1500L, 3750L, 7500L, 75L);
+ assertValues(stats, 1, 15 * MINUTE_IN_MILLIS, 750L, 1500L, 3750L, 7500L, 75L);
// final bucket should have (4/20 of value)
- assertValues(stats, 2, 200L, 400L, 1000L, 2000L, 20L);
+ assertValues(stats, 2, 4 * MINUTE_IN_MILLIS, 200L, 400L, 1000L, 2000L, 20L);
}
public void testRecordGapBuckets() throws Exception {
@@ -150,8 +150,8 @@
// we should have two buckets, far apart from each other
assertEquals(2, stats.size());
- assertValues(stats, 0, 128L, 2L, 256L, 4L, 1L);
- assertValues(stats, 1, 64L, 1L, 512L, 8L, 2L);
+ assertValues(stats, 0, SECOND_IN_MILLIS, 128L, 2L, 256L, 4L, 1L);
+ assertValues(stats, 1, SECOND_IN_MILLIS, 64L, 1L, 512L, 8L, 2L);
// now record something in middle, spread across two buckets
final long middleStart = TEST_START + DAY_IN_MILLIS;
@@ -161,10 +161,10 @@
// now should have four buckets, with new record in middle two buckets
assertEquals(4, stats.size());
- 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);
+ assertValues(stats, 0, SECOND_IN_MILLIS, 128L, 2L, 256L, 4L, 1L);
+ assertValues(stats, 1, HOUR_IN_MILLIS, 1024L, 2L, 1024L, 2L, 1L);
+ assertValues(stats, 2, HOUR_IN_MILLIS, 1024L, 2L, 1024L, 2L, 1L);
+ assertValues(stats, 3, SECOND_IN_MILLIS, 64L, 1L, 512L, 8L, 2L);
}
public void testRecordOverlapBuckets() throws Exception {
@@ -180,8 +180,8 @@
// should have two buckets, with some data mixed together
assertEquals(2, stats.size());
- assertValues(stats, 0, 768L, 7L, 768L, 7L, 6L);
- assertValues(stats, 1, 512L, 5L, 512L, 5L, 5L);
+ assertValues(stats, 0, SECOND_IN_MILLIS + (HOUR_IN_MILLIS / 2), 768L, 7L, 768L, 7L, 6L);
+ assertValues(stats, 1, (HOUR_IN_MILLIS / 2), 512L, 5L, 512L, 5L, 5L);
}
public void testRecordEntireGapIdentical() throws Exception {
@@ -345,11 +345,10 @@
history.recordData(0, MINUTE_IN_MILLIS,
new NetworkStats.Entry(1024L, 10L, 2048L, 20L, 4L));
- history.recordData(0, MINUTE_IN_MILLIS * 2,
+ history.recordData(0, 2 * MINUTE_IN_MILLIS,
new NetworkStats.Entry(2L, 2L, 2L, 2L, 2L));
- assertValues(
- history, Long.MIN_VALUE, Long.MAX_VALUE, 1026L, UNKNOWN, 2050L, UNKNOWN, UNKNOWN);
+ assertFullValues(history, UNKNOWN, 1026L, UNKNOWN, 2050L, UNKNOWN, UNKNOWN);
}
public void testIgnoreFieldsRecordIn() throws Exception {
@@ -361,7 +360,7 @@
new NetworkStats.Entry(1024L, 10L, 2048L, 20L, 4L));
partial.recordEntireHistory(full);
- assertValues(partial, Long.MIN_VALUE, Long.MAX_VALUE, UNKNOWN, 10L, UNKNOWN, UNKNOWN, 4L);
+ assertFullValues(partial, UNKNOWN, UNKNOWN, 10L, UNKNOWN, UNKNOWN, 4L);
}
public void testIgnoreFieldsRecordOut() throws Exception {
@@ -373,12 +372,12 @@
new NetworkStats.Entry(1024L, 10L, 2048L, 20L, 4L));
full.recordEntireHistory(partial);
- assertValues(full, Long.MIN_VALUE, Long.MAX_VALUE, 0L, 10L, 0L, 0L, 4L);
+ assertFullValues(full, MINUTE_IN_MILLIS, 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,
+ before.recordData(0, 4 * MINUTE_IN_MILLIS,
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));
@@ -391,8 +390,8 @@
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);
+ assertFullValues(before, 5 * MINUTE_IN_MILLIS, 1034L, 30L, 2078L, 60L, 54L);
+ assertFullValues(after, 5 * MINUTE_IN_MILLIS, 1034L, 30L, 2078L, 60L, 54L);
}
public void testVarLong() throws Exception {
@@ -441,9 +440,10 @@
assertEquals("unexpected txBytes", txBytes, entry.txBytes);
}
- private static void assertValues(NetworkStatsHistory stats, int index, long rxBytes,
- long rxPackets, long txBytes, long txPackets, long operations) {
+ private static void assertValues(NetworkStatsHistory stats, int index, long activeTime,
+ long rxBytes, long rxPackets, long txBytes, long txPackets, long operations) {
final NetworkStatsHistory.Entry entry = stats.getValues(index, null);
+ assertEquals("unexpected activeTime", activeTime, entry.activeTime);
assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes);
assertEquals("unexpected rxPackets", rxPackets, entry.rxPackets);
assertEquals("unexpected txBytes", txBytes, entry.txBytes);
@@ -451,9 +451,17 @@
assertEquals("unexpected operations", operations, entry.operations);
}
- private static void assertValues(NetworkStatsHistory stats, long start, long end, long rxBytes,
+ private static void assertFullValues(NetworkStatsHistory stats, long activeTime, long rxBytes,
long rxPackets, long txBytes, long txPackets, long operations) {
+ assertValues(stats, Long.MIN_VALUE, Long.MAX_VALUE, activeTime, rxBytes, rxPackets, txBytes,
+ txPackets, operations);
+ }
+
+ private static void assertValues(NetworkStatsHistory stats, long start, long end,
+ long activeTime, long rxBytes, long rxPackets, long txBytes, long txPackets,
+ long operations) {
final NetworkStatsHistory.Entry entry = stats.getValues(start, end, null);
+ assertEquals("unexpected activeTime", activeTime, entry.activeTime);
assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes);
assertEquals("unexpected rxPackets", rxPackets, entry.rxPackets);
assertEquals("unexpected txBytes", txBytes, entry.txBytes);
diff --git a/core/tests/coretests/src/android/net/NetworkStatsTest.java b/core/tests/coretests/src/android/net/NetworkStatsTest.java
index 47ba88a..c36685d 100644
--- a/core/tests/coretests/src/android/net/NetworkStatsTest.java
+++ b/core/tests/coretests/src/android/net/NetworkStatsTest.java
@@ -17,7 +17,9 @@
package android.net;
import static android.net.NetworkStats.SET_DEFAULT;
+import static android.net.NetworkStats.SET_FOREGROUND;
import static android.net.NetworkStats.TAG_NONE;
+import static android.net.NetworkStats.UID_ALL;
import android.test.suitebuilder.annotation.SmallTest;
@@ -27,6 +29,7 @@
public class NetworkStatsTest extends TestCase {
private static final String TEST_IFACE = "test0";
+ private static final String TEST_IFACE2 = "test2";
private static final int TEST_UID = 1001;
private static final long TEST_START = 1194220800000L;
@@ -135,6 +138,44 @@
assertValues(result, 2, TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 20);
}
+ public void testSubtractMissingRows() throws Exception {
+ final NetworkStats before = new NetworkStats(TEST_START, 2)
+ .addValues(TEST_IFACE, UID_ALL, SET_DEFAULT, TAG_NONE, 1024L, 0L, 0L, 0L, 0)
+ .addValues(TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, 2048L, 0L, 0L, 0L, 0);
+
+ final NetworkStats after = new NetworkStats(TEST_START, 1)
+ .addValues(TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, 2049L, 2L, 3L, 4L, 0);
+
+ final NetworkStats result = after.subtract(before);
+
+ // should silently drop omitted rows
+ assertEquals(1, result.size());
+ assertValues(result, 0, TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, 1L, 2L, 3L, 4L, 0);
+ assertEquals(4L, result.getTotalBytes());
+ }
+
+ public void testTotalBytes() throws Exception {
+ final NetworkStats iface = new NetworkStats(TEST_START, 2)
+ .addValues(TEST_IFACE, UID_ALL, SET_DEFAULT, TAG_NONE, 128L, 0L, 0L, 0L, 0L)
+ .addValues(TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, 256L, 0L, 0L, 0L, 0L);
+ assertEquals(384L, iface.getTotalBytes());
+
+ final NetworkStats uidSet = new NetworkStats(TEST_START, 3)
+ .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 32L, 0L, 0L, 0L, 0L)
+ .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 32L, 0L, 0L, 0L, 0L)
+ .addValues(TEST_IFACE, 101, SET_FOREGROUND, TAG_NONE, 32L, 0L, 0L, 0L, 0L);
+ assertEquals(96L, uidSet.getTotalBytes());
+
+ final NetworkStats uidTag = new NetworkStats(TEST_START, 3)
+ .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 16L, 0L, 0L, 0L, 0L)
+ .addValues(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, 16L, 0L, 0L, 0L, 0L)
+ .addValues(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, 8L, 0L, 0L, 0L, 0L)
+ .addValues(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, 16L, 0L, 0L, 0L, 0L)
+ .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 16L, 0L, 0L, 0L, 0L)
+ .addValues(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, 8L, 0L, 0L, 0L, 0L);
+ assertEquals(64L, uidTag.getTotalBytes());
+ }
+
private static void assertValues(NetworkStats stats, int index, String iface, int uid, int set,
int tag, long rxBytes, long rxPackets, long txBytes, long txPackets, int operations) {
final NetworkStats.Entry entry = stats.getValues(index, null);
diff --git a/data/fonts/Roboto-Bold.ttf b/data/fonts/Roboto-Bold.ttf
old mode 100755
new mode 100644
index 32c1794..f9311fb
--- a/data/fonts/Roboto-Bold.ttf
+++ b/data/fonts/Roboto-Bold.ttf
Binary files differ
diff --git a/data/fonts/Roboto-BoldItalic.ttf b/data/fonts/Roboto-BoldItalic.ttf
old mode 100755
new mode 100644
index 551bae2..ae92697
--- a/data/fonts/Roboto-BoldItalic.ttf
+++ b/data/fonts/Roboto-BoldItalic.ttf
Binary files differ
diff --git a/data/fonts/Roboto-Italic.ttf b/data/fonts/Roboto-Italic.ttf
old mode 100755
new mode 100644
index 9795cc0..109b642
--- a/data/fonts/Roboto-Italic.ttf
+++ b/data/fonts/Roboto-Italic.ttf
Binary files differ
diff --git a/data/fonts/Roboto-Regular.ttf b/data/fonts/Roboto-Regular.ttf
old mode 100755
new mode 100644
index 8545f29..2568835
--- a/data/fonts/Roboto-Regular.ttf
+++ b/data/fonts/Roboto-Regular.ttf
Binary files differ
diff --git a/data/sounds/AudioPackage7.mk b/data/sounds/AudioPackage7.mk
new file mode 100755
index 0000000..4f237161
--- /dev/null
+++ b/data/sounds/AudioPackage7.mk
@@ -0,0 +1,63 @@
+#
+# Audio Package 7 - Tuna
+#
+# Include this file in a product makefile to include these audio files
+#
+#
+
+LOCAL_PATH:= frameworks/base/data/sounds
+
+PRODUCT_COPY_FILES += \
+ $(LOCAL_PATH)/alarms/ogg/Cesium.ogg:system/media/audio/alarms/Cesium.ogg \
+ $(LOCAL_PATH)/alarms/ogg/Plutonium.ogg:system/media/audio/alarms/Plutonium.ogg \
+ $(LOCAL_PATH)/alarms/ogg/Scandium.ogg:system/media/audio/alarms/Scandium.ogg \
+ $(LOCAL_PATH)/alarms/ogg/Curium.ogg:system/media/audio/alarms/Curium.ogg \
+ $(LOCAL_PATH)/alarms/ogg/Fermium.ogg:system/media/audio/alarms/Fermium.ogg \
+ $(LOCAL_PATH)/alarms/ogg/Nobelium.ogg:system/media/audio/alarms/Nobelium.ogg \
+ $(LOCAL_PATH)/alarms/ogg/Copernicium.ogg:system/media/audio/alarms/Copernicium.ogg \
+ $(LOCAL_PATH)/alarms/ogg/Hassium.ogg:system/media/audio/alarms/Hassium.ogg \
+ $(LOCAL_PATH)/alarms/ogg/Neptunium.ogg:system/media/audio/alarms/Neptunium.ogg \
+ $(LOCAL_PATH)/effects/ogg/Effect_Tick.ogg:system/media/audio/ui/Effect_Tick.ogg \
+ $(LOCAL_PATH)/effects/ogg/KeypressStandard_24.ogg:system/media/audio/ui/KeypressStandard.ogg \
+ $(LOCAL_PATH)/effects/ogg/KeypressSpacebar_24.ogg:system/media/audio/ui/KeypressSpacebar.ogg \
+ $(LOCAL_PATH)/effects/ogg/KeypressDelete_24.ogg:system/media/audio/ui/KeypressDelete.ogg \
+ $(LOCAL_PATH)/effects/ogg/KeypressReturn_24.ogg:system/media/audio/ui/KeypressReturn.ogg \
+ $(LOCAL_PATH)/effects/ogg/VideoRecord.ogg:system/media/audio/ui/VideoRecord.ogg \
+ $(LOCAL_PATH)/effects/ogg/CameraShutter.ogg:system/media/audio/ui/camera_click.ogg \
+ $(LOCAL_PATH)/effects/ogg/LowBattery.ogg:system/media/audio/ui/LowBattery.ogg \
+ $(LOCAL_PATH)/effects/ogg/Dock.ogg:system/media/audio/ui/Dock.ogg \
+ $(LOCAL_PATH)/effects/ogg/Undock.ogg:system/media/audio/ui/Undock.ogg \
+ $(LOCAL_PATH)/effects/ogg/Lock.ogg:system/media/audio/ui/Lock.ogg \
+ $(LOCAL_PATH)/effects/ogg/Unlock.ogg:system/media/audio/ui/Unlock.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Altair.ogg:system/media/audio/notifications/Altair.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Antares.ogg:system/media/audio/notifications/Antares.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Deneb.ogg:system/media/audio/notifications/Deneb.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Lalande.ogg:system/media/audio/notifications/Lalande.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Hojus.ogg:system/media/audio/notifications/Hojus.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Proxima.ogg:system/media/audio/notifications/Proxima.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Betelgeuse.ogg:system/media/audio/notifications/Betelgeuse.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Mira.ogg:system/media/audio/notifications/Mira.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Upsilon.ogg:system/media/audio/notifications/Upsilon.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/Andromeda.ogg:system/media/audio/ringtones/Andromeda.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/Aquila.ogg:system/media/audio/ringtones/Aquila.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/ArgoNavis.ogg:system/media/audio/ringtones/ArgoNavis.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/Bootes.ogg:system/media/audio/ringtones/Bootes.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/CanisMajor.ogg:system/media/audio/ringtones/CanisMajor.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/Carina.ogg:system/media/audio/ringtones/Carina.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/Cassiopeia.ogg:system/media/audio/ringtones/Cassiopeia.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/Centaurus.ogg:system/media/audio/ringtones/Centaurus.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/Cygnus.ogg:system/media/audio/ringtones/Cygnus.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/Draco.ogg:system/media/audio/ringtones/Draco.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/Hydra.ogg:system/media/audio/ringtones/Hydra.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/Lyra.ogg:system/media/audio/ringtones/Lyra.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/Machina.ogg:system/media/audio/ringtones/Machina.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/Orion.ogg:system/media/audio/ringtones/Orion.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/Pegasus.ogg:system/media/audio/ringtones/Pegasus.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/Pyxis.ogg:system/media/audio/ringtones/Pyxis.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/Rigel.ogg:system/media/audio/ringtones/Rigel.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/Scarabaeus.ogg:system/media/audio/ringtones/Scarabaeus.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/Sceptrum.ogg:system/media/audio/ringtones/Sceptrum.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/Solarium.ogg:system/media/audio/ringtones/Solarium.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/Testudo.ogg:system/media/audio/ringtones/Testudo.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/UrsaMinor.ogg:system/media/audio/ringtones/UrsaMinor.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/Vespa.ogg:system/media/audio/ringtones/Vespa.ogg
diff --git a/data/sounds/alarms/ogg/Copernicium.ogg b/data/sounds/alarms/ogg/Copernicium.ogg
new file mode 100644
index 0000000..c619e8b
--- /dev/null
+++ b/data/sounds/alarms/ogg/Copernicium.ogg
Binary files differ
diff --git a/data/sounds/alarms/ogg/Curium.ogg b/data/sounds/alarms/ogg/Curium.ogg
new file mode 100644
index 0000000..ebce391
--- /dev/null
+++ b/data/sounds/alarms/ogg/Curium.ogg
Binary files differ
diff --git a/data/sounds/alarms/ogg/Fermium.ogg b/data/sounds/alarms/ogg/Fermium.ogg
new file mode 100644
index 0000000..6132565
--- /dev/null
+++ b/data/sounds/alarms/ogg/Fermium.ogg
Binary files differ
diff --git a/data/sounds/alarms/ogg/Hassium.ogg b/data/sounds/alarms/ogg/Hassium.ogg
new file mode 100644
index 0000000..408b7c2
--- /dev/null
+++ b/data/sounds/alarms/ogg/Hassium.ogg
Binary files differ
diff --git a/data/sounds/alarms/ogg/Neptunium.ogg b/data/sounds/alarms/ogg/Neptunium.ogg
new file mode 100644
index 0000000..058e2db
--- /dev/null
+++ b/data/sounds/alarms/ogg/Neptunium.ogg
Binary files differ
diff --git a/data/sounds/alarms/ogg/Nobelium.ogg b/data/sounds/alarms/ogg/Nobelium.ogg
new file mode 100644
index 0000000..33878c9
--- /dev/null
+++ b/data/sounds/alarms/ogg/Nobelium.ogg
Binary files differ
diff --git a/data/sounds/effects/ogg/CameraShutter.ogg b/data/sounds/effects/ogg/CameraShutter.ogg
new file mode 100644
index 0000000..1b67dac
--- /dev/null
+++ b/data/sounds/effects/ogg/CameraShutter.ogg
Binary files differ
diff --git a/data/sounds/effects/ogg/Dock.ogg b/data/sounds/effects/ogg/Dock.ogg
old mode 100755
new mode 100644
index a1c1f2c..caa8eeb
--- a/data/sounds/effects/ogg/Dock.ogg
+++ b/data/sounds/effects/ogg/Dock.ogg
Binary files differ
diff --git a/data/sounds/effects/ogg/KeypressDelete_24.ogg b/data/sounds/effects/ogg/KeypressDelete_24.ogg
new file mode 100644
index 0000000..2503c3e
--- /dev/null
+++ b/data/sounds/effects/ogg/KeypressDelete_24.ogg
Binary files differ
diff --git a/data/sounds/effects/ogg/KeypressReturn_24.ogg b/data/sounds/effects/ogg/KeypressReturn_24.ogg
new file mode 100644
index 0000000..342eb12
--- /dev/null
+++ b/data/sounds/effects/ogg/KeypressReturn_24.ogg
Binary files differ
diff --git a/data/sounds/effects/ogg/KeypressSpacebar_24.ogg b/data/sounds/effects/ogg/KeypressSpacebar_24.ogg
new file mode 100644
index 0000000..9f17dd2
--- /dev/null
+++ b/data/sounds/effects/ogg/KeypressSpacebar_24.ogg
Binary files differ
diff --git a/data/sounds/effects/ogg/KeypressStandard_24.ogg b/data/sounds/effects/ogg/KeypressStandard_24.ogg
new file mode 100644
index 0000000..80d7d6d1
--- /dev/null
+++ b/data/sounds/effects/ogg/KeypressStandard_24.ogg
Binary files differ
diff --git a/data/sounds/effects/ogg/Lock.ogg b/data/sounds/effects/ogg/Lock.ogg
old mode 100755
new mode 100644
index deeba68..471258a
--- a/data/sounds/effects/ogg/Lock.ogg
+++ b/data/sounds/effects/ogg/Lock.ogg
Binary files differ
diff --git a/data/sounds/effects/ogg/Media_Volume.ogg b/data/sounds/effects/ogg/Media_Volume.ogg
index 88db9d9..b06656f 100644
--- a/data/sounds/effects/ogg/Media_Volume.ogg
+++ b/data/sounds/effects/ogg/Media_Volume.ogg
Binary files differ
diff --git a/data/sounds/effects/ogg/Undock.ogg b/data/sounds/effects/ogg/Undock.ogg
old mode 100755
new mode 100644
index 91e410e..28918f7
--- a/data/sounds/effects/ogg/Undock.ogg
+++ b/data/sounds/effects/ogg/Undock.ogg
Binary files differ
diff --git a/data/sounds/effects/ogg/Unlock.ogg b/data/sounds/effects/ogg/Unlock.ogg
old mode 100755
new mode 100644
index ac50288..1cd537b
--- a/data/sounds/effects/ogg/Unlock.ogg
+++ b/data/sounds/effects/ogg/Unlock.ogg
Binary files differ
diff --git a/data/sounds/effects/ogg/VideoRecord.ogg b/data/sounds/effects/ogg/VideoRecord.ogg
index 7afe9e6..28455c9 100644
--- a/data/sounds/effects/ogg/VideoRecord.ogg
+++ b/data/sounds/effects/ogg/VideoRecord.ogg
Binary files differ
diff --git a/data/sounds/notifications/ogg/Altair.ogg b/data/sounds/notifications/ogg/Altair.ogg
new file mode 100755
index 0000000..d84b59e
--- /dev/null
+++ b/data/sounds/notifications/ogg/Altair.ogg
Binary files differ
diff --git a/data/sounds/notifications/ogg/Antares.ogg b/data/sounds/notifications/ogg/Antares.ogg
new file mode 100755
index 0000000..9d60917
--- /dev/null
+++ b/data/sounds/notifications/ogg/Antares.ogg
Binary files differ
diff --git a/data/sounds/notifications/ogg/Betelgeuse.ogg b/data/sounds/notifications/ogg/Betelgeuse.ogg
new file mode 100644
index 0000000..83c7722
--- /dev/null
+++ b/data/sounds/notifications/ogg/Betelgeuse.ogg
Binary files differ
diff --git a/data/sounds/notifications/ogg/Deneb.ogg b/data/sounds/notifications/ogg/Deneb.ogg
new file mode 100755
index 0000000..e58b3b6
--- /dev/null
+++ b/data/sounds/notifications/ogg/Deneb.ogg
Binary files differ
diff --git a/data/sounds/notifications/ogg/Hojus.ogg b/data/sounds/notifications/ogg/Hojus.ogg
new file mode 100644
index 0000000..fc8f73f
--- /dev/null
+++ b/data/sounds/notifications/ogg/Hojus.ogg
Binary files differ
diff --git a/data/sounds/notifications/ogg/Lalande.ogg b/data/sounds/notifications/ogg/Lalande.ogg
new file mode 100755
index 0000000..b6e253a
--- /dev/null
+++ b/data/sounds/notifications/ogg/Lalande.ogg
Binary files differ
diff --git a/data/sounds/notifications/ogg/Mira.ogg b/data/sounds/notifications/ogg/Mira.ogg
new file mode 100644
index 0000000..f21e3c4
--- /dev/null
+++ b/data/sounds/notifications/ogg/Mira.ogg
Binary files differ
diff --git a/data/sounds/notifications/ogg/Proxima.ogg b/data/sounds/notifications/ogg/Proxima.ogg
new file mode 100644
index 0000000..235b5ca
--- /dev/null
+++ b/data/sounds/notifications/ogg/Proxima.ogg
Binary files differ
diff --git a/data/sounds/notifications/ogg/Upsilon.ogg b/data/sounds/notifications/ogg/Upsilon.ogg
new file mode 100644
index 0000000..036dcad
--- /dev/null
+++ b/data/sounds/notifications/ogg/Upsilon.ogg
Binary files differ
diff --git a/data/sounds/ringtones/ogg/Cassiopeia.ogg b/data/sounds/ringtones/ogg/Cassiopeia.ogg
index 942d4e4..61c4d27 100644
--- a/data/sounds/ringtones/ogg/Cassiopeia.ogg
+++ b/data/sounds/ringtones/ogg/Cassiopeia.ogg
Binary files differ
diff --git a/data/sounds/ringtones/ogg/Lyra.ogg b/data/sounds/ringtones/ogg/Lyra.ogg
index e4bf37a..b7f740d 100644
--- a/data/sounds/ringtones/ogg/Lyra.ogg
+++ b/data/sounds/ringtones/ogg/Lyra.ogg
Binary files differ
diff --git a/data/sounds/ringtones/ogg/Sceptrum.ogg b/data/sounds/ringtones/ogg/Sceptrum.ogg
index a006afe..89d64d70 100644
--- a/data/sounds/ringtones/ogg/Sceptrum.ogg
+++ b/data/sounds/ringtones/ogg/Sceptrum.ogg
Binary files differ
diff --git a/data/sounds/ringtones/ogg/Solarium.ogg b/data/sounds/ringtones/ogg/Solarium.ogg
index 108ba11..361367a 100644
--- a/data/sounds/ringtones/ogg/Solarium.ogg
+++ b/data/sounds/ringtones/ogg/Solarium.ogg
Binary files differ
diff --git a/data/sounds/ringtones/ogg/UrsaMinor.ogg b/data/sounds/ringtones/ogg/UrsaMinor.ogg
index 5591d73..a80801d 100644
--- a/data/sounds/ringtones/ogg/UrsaMinor.ogg
+++ b/data/sounds/ringtones/ogg/UrsaMinor.ogg
Binary files differ
diff --git a/data/sounds/ringtones/ogg/Vespa.ogg b/data/sounds/ringtones/ogg/Vespa.ogg
index 6fb8ebd..1f75ec8 100644
--- a/data/sounds/ringtones/ogg/Vespa.ogg
+++ b/data/sounds/ringtones/ogg/Vespa.ogg
Binary files differ
diff --git a/graphics/java/android/graphics/SurfaceTexture.java b/graphics/java/android/graphics/SurfaceTexture.java
index d62fd67..f3b62ec 100644
--- a/graphics/java/android/graphics/SurfaceTexture.java
+++ b/graphics/java/android/graphics/SurfaceTexture.java
@@ -93,7 +93,7 @@
* @param texName the OpenGL texture object name (e.g. generated via glGenTextures)
*/
public SurfaceTexture(int texName) {
- this(texName, true);
+ this(texName, false);
}
/**
@@ -104,6 +104,8 @@
* When the image stream comes from OpenGL, SurfaceTexture may run in the synchronous
* mode where the producer side may be blocked to avoid skipping frames. To avoid the
* thread block, set allowSynchronousMode to false.
+ *
+ * @hide
*/
public SurfaceTexture(int texName, boolean allowSynchronousMode) {
Looper looper;
diff --git a/include/media/stagefright/SurfaceMediaSource.h b/include/media/stagefright/SurfaceMediaSource.h
index 1affb8a..74d54d11 100644
--- a/include/media/stagefright/SurfaceMediaSource.h
+++ b/include/media/stagefright/SurfaceMediaSource.h
@@ -182,9 +182,9 @@
protected:
- // freeAllBuffers frees the resources (both GraphicBuffer and EGLImage) for
+ // freeAllBuffersLocked frees the resources (both GraphicBuffer and EGLImage) for
// all slots.
- void freeAllBuffers();
+ void freeAllBuffersLocked();
static bool isExternalFormat(uint32_t format);
private:
@@ -337,8 +337,15 @@
// Set to a default of 30 fps if not specified by the client side
int32_t mFrameRate;
- // mStarted is a flag to check if the recording has started
- bool mStarted;
+ // mStopped is a flag to check if the recording is going on
+ bool mStopped;
+
+ // mNumFramesReceived indicates the number of frames recieved from
+ // the client side
+ int mNumFramesReceived;
+ // mNumFramesEncoded indicates the number of frames passed on to the
+ // encoder
+ int mNumFramesEncoded;
// mFrameAvailableCondition condition used to indicate whether there
// is a frame available for dequeuing
diff --git a/include/media/stagefright/openmax/OMX_IVCommon.h b/include/media/stagefright/openmax/OMX_IVCommon.h
index 97170d7..65b6339 100644
--- a/include/media/stagefright/openmax/OMX_IVCommon.h
+++ b/include/media/stagefright/openmax/OMX_IVCommon.h
@@ -154,7 +154,8 @@
* Gralloc Buffers.
* FIXME: In the process of reserving some enum values for
* Android-specific OMX IL colorformats. Change this enum to
- * an acceptable range once that is done.*/
+ * an acceptable range once that is done.
+ * */
OMX_COLOR_FormatAndroidOpaque = 0x7F000001,
OMX_TI_COLOR_FormatYUV420PackedSemiPlanar = 0x7F000100,
OMX_QCOM_COLOR_FormatYVU420SemiPlanar = 0x7FA30C00,
diff --git a/include/ui/GraphicBuffer.h b/include/ui/GraphicBuffer.h
index 370253a..b9deafc 100644
--- a/include/ui/GraphicBuffer.h
+++ b/include/ui/GraphicBuffer.h
@@ -62,6 +62,7 @@
USAGE_HW_TEXTURE = GRALLOC_USAGE_HW_TEXTURE,
USAGE_HW_RENDER = GRALLOC_USAGE_HW_RENDER,
USAGE_HW_2D = GRALLOC_USAGE_HW_2D,
+ USAGE_HW_COMPOSER = GRALLOC_USAGE_HW_COMPOSER,
USAGE_HW_MASK = GRALLOC_USAGE_HW_MASK
};
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index acc2b23..fe57e8a 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -3072,11 +3072,13 @@
/**
* Update the remote control displays with the new "focused" client generation
*/
- private void setNewRcClientGenerationOnDisplays_syncRcStack(int newClientGeneration) {
+ private void setNewRcClientOnDisplays_syncAfRcsCurrc(int newClientGeneration,
+ ComponentName newClientEventReceiver, boolean clearing) {
// NOTE: Only one IRemoteControlDisplay supported in this implementation
if (mRcDisplay != null) {
try {
- mRcDisplay.setCurrentClientGenerationId(newClientGeneration);
+ mRcDisplay.setCurrentClientId(
+ newClientGeneration, newClientEventReceiver, clearing);
} catch (RemoteException e) {
Log.e(TAG, "Dead display in onRcDisplayUpdate() "+e);
// if we had a display before, stop monitoring its death
@@ -3089,7 +3091,7 @@
/**
* Update the remote control clients with the new "focused" client generation
*/
- private void setNewRcClientGenerationOnClients_syncRcStack(int newClientGeneration) {
+ private void setNewRcClientGenerationOnClients_syncAfRcsCurrc(int newClientGeneration) {
Iterator<RemoteControlStackEntry> stackIterator = mRCStack.iterator();
while(stackIterator.hasNext()) {
RemoteControlStackEntry se = stackIterator.next();
@@ -3106,15 +3108,20 @@
}
/**
- * Update the displays and clients with the new "focused" client generation
+ * Update the displays and clients with the new "focused" client generation and name
+ * @param newClientGeneration the new generation value matching a client update
+ * @param newClientEventReceiver the media button event receiver associated with the client.
+ * May be null, which implies there is no registered media button event receiver.
+ * @param clearing true if the new client generation value maps to a remote control update
+ * where the display should be cleared.
*/
- private void setNewRcClientGeneration(int newClientGeneration) {
- synchronized(mRCStack) {
- // send the new valid client generation ID to all displays
- setNewRcClientGenerationOnDisplays_syncRcStack(newClientGeneration);
- // send the new valid client generation ID to all clients
- setNewRcClientGenerationOnClients_syncRcStack(newClientGeneration);
- }
+ private void setNewRcClient_syncAfRcsCurrc(int newClientGeneration,
+ ComponentName newClientEventReceiver, boolean clearing) {
+ // send the new valid client generation ID to all displays
+ setNewRcClientOnDisplays_syncAfRcsCurrc(newClientGeneration, newClientEventReceiver,
+ clearing);
+ // send the new valid client generation ID to all clients
+ setNewRcClientGenerationOnClients_syncAfRcsCurrc(newClientGeneration);
}
/**
@@ -3124,11 +3131,13 @@
// TODO remove log before release
Log.i(TAG, "Clear remote control display");
- synchronized(mCurrentRcLock) {
- mCurrentRcClientGen++;
-
- // synchronously update the displays and clients with the new client generation
- setNewRcClientGeneration(mCurrentRcClientGen);
+ synchronized(mRCStack) {
+ synchronized(mCurrentRcLock) {
+ mCurrentRcClientGen++;
+ // synchronously update the displays and clients with the new client generation
+ setNewRcClient_syncAfRcsCurrc(mCurrentRcClientGen,
+ null /*event receiver*/, true /*clearing*/);
+ }
}
}
@@ -3136,28 +3145,32 @@
* Called when processing MSG_RCDISPLAY_UPDATE event
*/
private void onRcDisplayUpdate(RemoteControlStackEntry rcse, int flags /* USED ?*/) {
- synchronized(mCurrentRcLock) {
- if ((mCurrentRcClient != null) && (mCurrentRcClient.equals(rcse.mRcClient))) {
- // TODO remove log before release
- Log.i(TAG, "Display/update remote control ");
+ synchronized(mRCStack) {
+ synchronized(mCurrentRcLock) {
+ if ((mCurrentRcClient != null) && (mCurrentRcClient.equals(rcse.mRcClient))) {
+ // TODO remove log before release
+ Log.i(TAG, "Display/update remote control ");
- mCurrentRcClientGen++;
+ mCurrentRcClientGen++;
+ // synchronously update the displays and clients with
+ // the new client generation
+ setNewRcClient_syncAfRcsCurrc(mCurrentRcClientGen,
+ rcse.mReceiverComponent /*event receiver*/,
+ false /*clearing*/);
- // synchronously update the displays and clients with the new client generation
- setNewRcClientGeneration(mCurrentRcClientGen);
-
- // ask the current client that it needs to send info
- try {
- mCurrentRcClient.onInformationRequested(mCurrentRcClientGen,
- flags, mArtworkExpectedWidth, mArtworkExpectedHeight);
- } catch (RemoteException e) {
- Log.e(TAG, "Current valid remote client is dead: "+e);
- mCurrentRcClient = null;
+ // ask the current client that it needs to send info
+ try {
+ mCurrentRcClient.onInformationRequested(mCurrentRcClientGen,
+ flags, mArtworkExpectedWidth, mArtworkExpectedHeight);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Current valid remote client is dead: "+e);
+ mCurrentRcClient = null;
+ }
+ } else {
+ // 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 {
- // 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)
}
}
}
@@ -3320,10 +3333,31 @@
}
}
- /** see AudioManager.unregisterRemoteControlClient(ComponentName eventReceiver, ...) */
+ /**
+ * see AudioManager.unregisterRemoteControlClient(ComponentName eventReceiver, ...)
+ * rcClient is guaranteed non-null
+ */
public void unregisterRemoteControlClient(ComponentName eventReceiver,
IRemoteControlClient rcClient) {
- //FIXME implement
+ synchronized(mAudioFocusLock) {
+ synchronized(mRCStack) {
+ Iterator<RemoteControlStackEntry> stackIterator = mRCStack.iterator();
+ while(stackIterator.hasNext()) {
+ RemoteControlStackEntry rcse = stackIterator.next();
+ if ((rcse.mReceiverComponent.equals(eventReceiver))
+ && rcClient.equals(rcse.mRcClient)) {
+ // we found the IRemoteControlClient to unregister
+ // stop monitoring its death
+ rcse.unlinkToRcClientDeath();
+ // reset the client-related fields
+ rcse.mRcClient = null;
+ rcse.mRcClientName = null;
+ rcse.mRcClientDeathHandler = null;
+ rcse.mCallingPackageName = null;
+ }
+ }
+ }
+ }
}
/**
diff --git a/media/java/android/media/IRemoteControlDisplay.aidl b/media/java/android/media/IRemoteControlDisplay.aidl
index d000906..fd50b7e 100644
--- a/media/java/android/media/IRemoteControlDisplay.aidl
+++ b/media/java/android/media/IRemoteControlDisplay.aidl
@@ -16,6 +16,7 @@
package android.media;
+import android.content.ComponentName;
import android.graphics.Bitmap;
import android.os.Bundle;
@@ -29,15 +30,23 @@
{
/**
* Sets the generation counter of the current client that is displayed on the remote control.
+ * @param clientGeneration the new RemoteControlClient generation
+ * @param clientEventReceiver the media button event receiver associated with the client.
+ * May be null, which implies there is no registered media button event receiver. This
+ * parameter is supplied as an optimization so a display can directly target media button
+ * events to the client.
+ * @param clearing true if the new client generation value maps to a remote control update
+ * where the display should be cleared.
*/
- void setCurrentClientGenerationId(int clientGeneration);
+ void setCurrentClientId(int clientGeneration, in ComponentName clientEventReceiver,
+ boolean clearing);
void setPlaybackState(int generationId, int state);
- void setMetadata(int generationId, in Bundle metadata);
-
void setTransportControlFlags(int generationId, int transportControlFlags);
+ void setMetadata(int generationId, in Bundle metadata);
+
void setArtwork(int generationId, in Bitmap artwork);
/**
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index f2673b3..bc42a42 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -1318,6 +1318,7 @@
status_t AwesomePlayer::seekTo_l(int64_t timeUs) {
if (mRTSPController != NULL) {
+ mSeekNotificationSent = false;
mRTSPController->seekAsync(timeUs, OnRTSPSeekDoneWrapper, this);
return OK;
}
diff --git a/media/libstagefright/CameraSource.cpp b/media/libstagefright/CameraSource.cpp
index ac3565f6..256f3ba 100755
--- a/media/libstagefright/CameraSource.cpp
+++ b/media/libstagefright/CameraSource.cpp
@@ -635,6 +635,12 @@
mStarted = false;
mFrameAvailableCondition.signal();
+ int64_t token;
+ bool isTokenValid = false;
+ if (mCamera != 0) {
+ token = IPCThreadState::self()->clearCallingIdentity();
+ isTokenValid = true;
+ }
releaseQueuedFrames();
while (!mFramesBeingEncoded.empty()) {
if (NO_ERROR !=
@@ -645,6 +651,9 @@
}
stopCameraRecording();
releaseCamera();
+ if (isTokenValid) {
+ IPCThreadState::self()->restoreCallingIdentity(token);
+ }
if (mCollectStats) {
LOGI("Frames received/encoded/dropped: %d/%d/%d in %lld us",
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index 27dfeab..7f09319 100755
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -808,7 +808,7 @@
}
if (format.eCompressionFormat == compressionFormat
- && format.eColorFormat == colorFormat) {
+ && format.eColorFormat == colorFormat) {
found = true;
break;
}
@@ -838,6 +838,15 @@
case OMX_COLOR_FormatYUV420Planar:
case OMX_COLOR_FormatYUV420SemiPlanar:
case OMX_TI_COLOR_FormatYUV420PackedSemiPlanar:
+ /*
+ * FIXME: For the Opaque color format, the frame size does not
+ * need to be (w*h*3)/2. It just needs to
+ * be larger than certain minimum buffer size. However,
+ * currently, this opaque foramt has been tested only on
+ * YUV420 formats. If that is changed, then we need to revisit
+ * this part in the future
+ */
+ case OMX_COLOR_FormatAndroidOpaque:
return (width * height * 3) / 2;
default:
@@ -887,7 +896,7 @@
// Make sure that omx component does not overwrite
// the incremented index (bug 2897413).
CHECK_EQ(index, portFormat.nIndex);
- if ((portFormat.eColorFormat == colorFormat)) {
+ if (portFormat.eColorFormat == colorFormat) {
LOGV("Found supported color format: %d", portFormat.eColorFormat);
return OK; // colorFormat is supported!
}
@@ -2316,6 +2325,7 @@
{
CODEC_LOGV("OMX_EventPortSettingsChanged(port=%ld, data2=0x%08lx)",
data1, data2);
+ CHECK(mFilledBuffers.empty());
if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
onPortSettingsChanged(data1);
@@ -2923,6 +2933,7 @@
size_t offset = 0;
int32_t n = 0;
+
for (;;) {
MediaBuffer *srcBuffer;
if (mSeekTimeUs >= 0) {
@@ -3021,6 +3032,7 @@
CHECK(info->mMediaBuffer == NULL);
info->mMediaBuffer = srcBuffer;
} else {
+ CHECK(srcBuffer->data() != NULL) ;
memcpy((uint8_t *)info->mData + offset,
(const uint8_t *)srcBuffer->data()
+ srcBuffer->range_offset(),
diff --git a/media/libstagefright/SurfaceMediaSource.cpp b/media/libstagefright/SurfaceMediaSource.cpp
index ddfd9ff..c2e6707 100644
--- a/media/libstagefright/SurfaceMediaSource.cpp
+++ b/media/libstagefright/SurfaceMediaSource.cpp
@@ -13,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
// #define LOG_NDEBUG 0
#define LOG_TAG "SurfaceMediaSource"
@@ -47,7 +46,9 @@
mSynchronousMode(true),
mConnectedApi(NO_CONNECTED_API),
mFrameRate(30),
- mStarted(false) {
+ mNumFramesReceived(0),
+ mNumFramesEncoded(0),
+ mStopped(false) {
LOGV("SurfaceMediaSource::SurfaceMediaSource");
sp<ISurfaceComposer> composer(ComposerService::getComposerService());
mGraphicBufferAlloc = composer->createGraphicBufferAlloc();
@@ -55,10 +56,9 @@
SurfaceMediaSource::~SurfaceMediaSource() {
LOGV("SurfaceMediaSource::~SurfaceMediaSource");
- if (mStarted) {
+ if (!mStopped) {
stop();
}
- freeAllBuffers();
}
size_t SurfaceMediaSource::getQueuedCount() const {
@@ -139,12 +139,12 @@
// here we're guaranteed that the client doesn't have dequeued buffers
// and will release all of its buffer references.
- freeAllBuffers();
mBufferCount = bufferCount;
mClientBufferCount = bufferCount;
mCurrentSlot = INVALID_BUFFER_SLOT;
mQueue.clear();
mDequeueCondition.signal();
+ freeAllBuffersLocked();
return OK;
}
@@ -164,7 +164,7 @@
status_t SurfaceMediaSource::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h,
uint32_t format, uint32_t usage) {
LOGV("dequeueBuffer");
-
+ Mutex::Autolock lock(mMutex);
// Check for the buffer size- the client should just use the
// default width and height, and not try to set those.
@@ -184,10 +184,7 @@
return BAD_VALUE;
}
- Mutex::Autolock lock(mMutex);
-
status_t returnFlags(OK);
-
int found, foundSync;
int dequeuedCount = 0;
bool tryAgain = true;
@@ -218,6 +215,9 @@
LOGV("Waiting for the FIFO to drain");
mDequeueCondition.wait(mMutex);
}
+ if (mStopped) {
+ return NO_INIT;
+ }
// need to check again since the mode could have changed
// while we were waiting
minBufferCountNeeded = mSynchronousMode ?
@@ -228,7 +228,7 @@
((mServerBufferCount != mBufferCount) ||
(mServerBufferCount < minBufferCountNeeded))) {
// here we're guaranteed that mQueue is empty
- freeAllBuffers();
+ freeAllBuffersLocked();
mBufferCount = mServerBufferCount;
if (mBufferCount < minBufferCountNeeded)
mBufferCount = minBufferCountNeeded;
@@ -290,9 +290,12 @@
// for for some buffers to be consumed
tryAgain = mSynchronousMode && (foundSync == INVALID_BUFFER_SLOT);
if (tryAgain) {
- LOGW("Waiting..In synchronous mode and no buffer to dQ");
+ LOGV("Waiting..In synchronous mode and no buffer to dequeue");
mDequeueCondition.wait(mMutex);
}
+ if (mStopped) {
+ return NO_INIT;
+ }
}
if (mSynchronousMode && found == INVALID_BUFFER_SLOT) {
@@ -304,7 +307,7 @@
return -EBUSY;
}
- const int buf = found;
+ const int bufIndex = found;
*outBuf = found;
const bool useDefaultSize = !w && !h;
@@ -322,9 +325,9 @@
// buffer is now in DEQUEUED (but can also be current at the same time,
// if we're in synchronous mode)
- mSlots[buf].mBufferState = BufferSlot::DEQUEUED;
+ mSlots[bufIndex].mBufferState = BufferSlot::DEQUEUED;
- const sp<GraphicBuffer>& buffer(mSlots[buf].mGraphicBuffer);
+ const sp<GraphicBuffer>& buffer(mSlots[bufIndex].mGraphicBuffer);
if ((buffer == NULL) ||
(uint32_t(buffer->width) != w) ||
(uint32_t(buffer->height) != h) ||
@@ -342,22 +345,25 @@
if (updateFormat) {
mPixelFormat = format;
}
- mSlots[buf].mGraphicBuffer = graphicBuffer;
- mSlots[buf].mRequestBufferCalled = false;
+ mSlots[bufIndex].mGraphicBuffer = graphicBuffer;
+ mSlots[bufIndex].mRequestBufferCalled = false;
returnFlags |= ISurfaceTexture::BUFFER_NEEDS_REALLOCATION;
}
return returnFlags;
}
+// TODO: clean this up
status_t SurfaceMediaSource::setSynchronousMode(bool enabled) {
Mutex::Autolock lock(mMutex);
+ if (mStopped) {
+ LOGE("setSynchronousMode: SurfaceMediaSource has been stopped!");
+ return NO_INIT;
+ }
- status_t err = OK;
if (!enabled) {
- // going to asynchronous mode, drain the queue
- while (mSynchronousMode != enabled && !mQueue.isEmpty()) {
- mDequeueCondition.wait(mMutex);
- }
+ // Async mode is not allowed
+ LOGE("SurfaceMediaSource can be used only synchronous mode!");
+ return INVALID_OPERATION;
}
if (mSynchronousMode != enabled) {
@@ -368,13 +374,19 @@
mSynchronousMode = enabled;
mDequeueCondition.signal();
}
- return err;
+ return OK;
}
status_t SurfaceMediaSource::connect(int api,
uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform) {
LOGV("SurfaceMediaSource::connect");
Mutex::Autolock lock(mMutex);
+
+ if (mStopped) {
+ LOGE("Connect: SurfaceMediaSource has been stopped!");
+ return NO_INIT;
+ }
+
status_t err = NO_ERROR;
switch (api) {
case NATIVE_WINDOW_API_EGL:
@@ -397,9 +409,25 @@
return err;
}
+// This is called by the client side when it is done
+// TODO: Currently, this also sets mStopped to true which
+// is needed for unblocking the encoder which might be
+// waiting to read more frames. So if on the client side,
+// the same thread supplies the frames and also calls stop
+// on the encoder, the client has to call disconnect before
+// it calls stop.
+// In the case of the camera,
+// that need not be required since the thread supplying the
+// frames is separate than the one calling stop.
status_t SurfaceMediaSource::disconnect(int api) {
LOGV("SurfaceMediaSource::disconnect");
Mutex::Autolock lock(mMutex);
+
+ if (mStopped) {
+ LOGE("disconnect: SurfaceMediaSoource is already stopped!");
+ return NO_INIT;
+ }
+
status_t err = NO_ERROR;
switch (api) {
case NATIVE_WINDOW_API_EGL:
@@ -408,6 +436,9 @@
case NATIVE_WINDOW_API_CAMERA:
if (mConnectedApi == api) {
mConnectedApi = NO_CONNECTED_API;
+ mStopped = true;
+ mDequeueCondition.signal();
+ mFrameAvailableCondition.signal();
} else {
err = -EINVAL;
}
@@ -419,45 +450,47 @@
return err;
}
-status_t SurfaceMediaSource::queueBuffer(int buf, int64_t timestamp,
+status_t SurfaceMediaSource::queueBuffer(int bufIndex, int64_t timestamp,
uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform) {
LOGV("queueBuffer");
Mutex::Autolock lock(mMutex);
- if (buf < 0 || buf >= mBufferCount) {
+ if (bufIndex < 0 || bufIndex >= mBufferCount) {
LOGE("queueBuffer: slot index out of range [0, %d]: %d",
- mBufferCount, buf);
+ mBufferCount, bufIndex);
return -EINVAL;
- } else if (mSlots[buf].mBufferState != BufferSlot::DEQUEUED) {
+ } else if (mSlots[bufIndex].mBufferState != BufferSlot::DEQUEUED) {
LOGE("queueBuffer: slot %d is not owned by the client (state=%d)",
- buf, mSlots[buf].mBufferState);
+ bufIndex, mSlots[bufIndex].mBufferState);
return -EINVAL;
- } else if (!mSlots[buf].mRequestBufferCalled) {
+ } else if (!mSlots[bufIndex].mRequestBufferCalled) {
LOGE("queueBuffer: slot %d was enqueued without requesting a "
- "buffer", buf);
+ "buffer", bufIndex);
return -EINVAL;
}
if (mSynchronousMode) {
// in synchronous mode we queue all buffers in a FIFO
- mQueue.push_back(buf);
- LOGV("Client queued buffer on slot: %d, Q size = %d",
- buf, mQueue.size());
+ mQueue.push_back(bufIndex);
+ mNumFramesReceived++;
+ LOGV("Client queued buf# %d @slot: %d, Q size = %d, handle = %p, timestamp = %lld",
+ mNumFramesReceived, bufIndex, mQueue.size(),
+ mSlots[bufIndex].mGraphicBuffer->handle, timestamp);
} else {
// in asynchronous mode we only keep the most recent buffer
if (mQueue.empty()) {
- mQueue.push_back(buf);
+ mQueue.push_back(bufIndex);
} else {
Fifo::iterator front(mQueue.begin());
// buffer currently queued is freed
mSlots[*front].mBufferState = BufferSlot::FREE;
// and we record the new buffer index in the queued list
- *front = buf;
+ *front = bufIndex;
}
}
- mSlots[buf].mBufferState = BufferSlot::QUEUED;
- mSlots[buf].mTimestamp = timestamp;
+ mSlots[bufIndex].mBufferState = BufferSlot::QUEUED;
+ mSlots[bufIndex].mTimestamp = timestamp;
// TODO: (Confirm) Don't want to signal dequeue here.
// May be just in asynchronous mode?
// mDequeueCondition.signal();
@@ -482,7 +515,7 @@
// wait to hear from StageFrightRecorder to set the buffer FREE
// Make sure this is called when the mutex is locked
status_t SurfaceMediaSource::onFrameReceivedLocked() {
- LOGV("On Frame Received");
+ LOGV("On Frame Received locked");
// Signal the encoder that a new frame has arrived
mFrameAvailableCondition.signal();
@@ -501,19 +534,19 @@
}
-void SurfaceMediaSource::cancelBuffer(int buf) {
+void SurfaceMediaSource::cancelBuffer(int bufIndex) {
LOGV("SurfaceMediaSource::cancelBuffer");
Mutex::Autolock lock(mMutex);
- if (buf < 0 || buf >= mBufferCount) {
+ if (bufIndex < 0 || bufIndex >= mBufferCount) {
LOGE("cancelBuffer: slot index out of range [0, %d]: %d",
- mBufferCount, buf);
+ mBufferCount, bufIndex);
return;
- } else if (mSlots[buf].mBufferState != BufferSlot::DEQUEUED) {
+ } else if (mSlots[bufIndex].mBufferState != BufferSlot::DEQUEUED) {
LOGE("cancelBuffer: slot %d is not owned by the client (state=%d)",
- buf, mSlots[buf].mBufferState);
+ bufIndex, mSlots[bufIndex].mBufferState);
return;
}
- mSlots[buf].mBufferState = BufferSlot::FREE;
+ mSlots[bufIndex].mBufferState = BufferSlot::FREE;
mDequeueCondition.signal();
}
@@ -531,8 +564,8 @@
mFrameAvailableListener = listener;
}
-void SurfaceMediaSource::freeAllBuffers() {
- LOGV("freeAllBuffers");
+void SurfaceMediaSource::freeAllBuffersLocked() {
+ LOGV("freeAllBuffersLocked");
for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
mSlots[i].mGraphicBuffer = 0;
mSlots[i].mBufferState = BufferSlot::FREE;
@@ -648,10 +681,7 @@
status_t SurfaceMediaSource::start(MetaData *params)
{
- LOGV("start");
- Mutex::Autolock lock(mMutex);
- CHECK(!mStarted);
- mStarted = true;
+ LOGV("started!");
return OK;
}
@@ -662,8 +692,11 @@
Mutex::Autolock lock(mMutex);
// TODO: Add waiting on mFrameCompletedCondition here?
- mStarted = false;
+ mStopped = true;
mFrameAvailableCondition.signal();
+ mDequeueCondition.signal();
+ mQueue.clear();
+ freeAllBuffersLocked();
return OK;
}
@@ -688,23 +721,25 @@
}
status_t SurfaceMediaSource::read( MediaBuffer **buffer,
- const ReadOptions *options)
+ const ReadOptions *options)
{
+ Mutex::Autolock autoLock(mMutex) ;
+
LOGV("Read. Size of queued buffer: %d", mQueue.size());
*buffer = NULL;
- Mutex::Autolock autoLock(mMutex) ;
// If the recording has started and the queue is empty, then just
// wait here till the frames come in from the client side
- while (mStarted && mQueue.empty()) {
+ while (!mStopped && mQueue.empty()) {
LOGV("NO FRAMES! Recorder waiting for FrameAvailableCondition");
mFrameAvailableCondition.wait(mMutex);
}
// If the loop was exited as a result of stopping the recording,
// it is OK
- if (!mStarted) {
- return OK;
+ if (mStopped) {
+ LOGV("Read: SurfaceMediaSource is stopped. Returning NO_INIT;");
+ return NO_INIT;
}
// Update the current buffer info
@@ -712,15 +747,20 @@
// can be more than one "current" slots.
Fifo::iterator front(mQueue.begin());
mCurrentSlot = *front;
+ mQueue.erase(front);
mCurrentBuf = mSlots[mCurrentSlot].mGraphicBuffer;
+ int64_t prevTimeStamp = mCurrentTimestamp;
mCurrentTimestamp = mSlots[mCurrentSlot].mTimestamp;
-
+ mNumFramesEncoded++;
// Pass the data to the MediaBuffer. Pass in only the metadata
passMetadataBufferLocked(buffer);
(*buffer)->setObserver(this);
(*buffer)->add_ref();
- (*buffer)->meta_data()->setInt64(kKeyTime, mCurrentTimestamp);
+ (*buffer)->meta_data()->setInt64(kKeyTime, mCurrentTimestamp / 1000);
+ LOGV("Frames encoded = %d, timestamp = %lld, time diff = %lld",
+ mNumFramesEncoded, mCurrentTimestamp / 1000,
+ mCurrentTimestamp / 1000 - prevTimeStamp / 1000);
return OK;
}
@@ -743,15 +783,17 @@
new MediaBuffer(4 + sizeof(buffer_handle_t));
char *data = (char *)tempBuffer->data();
if (data == NULL) {
- LOGE("Cannot allocate memory for passing buffer metadata!");
+ LOGE("Cannot allocate memory for metadata buffer!");
return;
}
OMX_U32 type = kMetadataBufferTypeGrallocSource;
memcpy(data, &type, 4);
memcpy(data + 4, &(mCurrentBuf->handle), sizeof(buffer_handle_t));
*buffer = tempBuffer;
-}
+ LOGV("handle = %p, , offset = %d, length = %d",
+ mCurrentBuf->handle, (*buffer)->range_length(), (*buffer)->range_offset());
+}
void SurfaceMediaSource::signalBufferReturned(MediaBuffer *buffer) {
LOGV("signalBufferReturned");
@@ -759,16 +801,19 @@
bool foundBuffer = false;
Mutex::Autolock autoLock(mMutex);
- if (!mStarted) {
- LOGW("signalBufferReturned: mStarted = false! Nothing to do!");
+ if (mStopped) {
+ LOGV("signalBufferReturned: mStopped = true! Nothing to do!");
return;
}
- for (Fifo::iterator it = mQueue.begin(); it != mQueue.end(); ++it) {
- CHECK(mSlots[*it].mGraphicBuffer != NULL);
- if (checkBufferMatchesSlot(*it, buffer)) {
- mSlots[*it].mBufferState = BufferSlot::FREE;
- mQueue.erase(it);
+ for (int id = 0; id < NUM_BUFFER_SLOTS; id++) {
+ if (mSlots[id].mGraphicBuffer == NULL) {
+ continue;
+ }
+ if (checkBufferMatchesSlot(id, buffer)) {
+ LOGV("Slot %d returned, matches handle = %p", id,
+ mSlots[id].mGraphicBuffer->handle);
+ mSlots[id].mBufferState = BufferSlot::FREE;
buffer->setObserver(0);
buffer->release();
mDequeueCondition.signal();
@@ -792,5 +837,4 @@
return mSlots[slot].mGraphicBuffer->handle == bufferHandle;
}
-
} // end of namespace android
diff --git a/media/libstagefright/tests/Android.mk b/media/libstagefright/tests/Android.mk
index 3ea8f39..357feb1 100644
--- a/media/libstagefright/tests/Android.mk
+++ b/media/libstagefright/tests/Android.mk
@@ -19,12 +19,13 @@
libbinder \
libcutils \
libgui \
- libstlport \
- libui \
- libutils \
+ libmedia \
libstagefright \
libstagefright_omx \
libstagefright_foundation \
+ libstlport \
+ libui \
+ libutils \
LOCAL_STATIC_LIBRARIES := \
libgtest \
diff --git a/media/libstagefright/tests/SurfaceMediaSource_test.cpp b/media/libstagefright/tests/SurfaceMediaSource_test.cpp
index 5b32b68..d643a0b 100644
--- a/media/libstagefright/tests/SurfaceMediaSource_test.cpp
+++ b/media/libstagefright/tests/SurfaceMediaSource_test.cpp
@@ -14,14 +14,17 @@
* limitations under the License.
*/
-#define LOG_TAG "SurfaceMediaSource_test"
// #define LOG_NDEBUG 0
+#define LOG_TAG "SurfaceMediaSource_test"
#include <gtest/gtest.h>
#include <utils/String8.h>
#include <utils/Errors.h>
+#include <fcntl.h>
+#include <unistd.h>
#include <media/stagefright/SurfaceMediaSource.h>
+#include <media/mediarecorder.h>
#include <gui/SurfaceTextureClient.h>
#include <ui/GraphicBuffer.h>
@@ -33,24 +36,322 @@
#include <ui/FramebufferNativeWindow.h>
#include <media/stagefright/MediaDebug.h>
+#include <media/stagefright/MediaBufferGroup.h>
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MetaData.h>
-#include <media/stagefright/MPEG4Writer.h>
#include <media/stagefright/OMXClient.h>
#include <media/stagefright/OMXCodec.h>
#include <OMX_Component.h>
#include "DummyRecorder.h"
+
namespace android {
+class GLTest : public ::testing::Test {
+protected:
+ GLTest():
+ mEglDisplay(EGL_NO_DISPLAY),
+ mEglSurface(EGL_NO_SURFACE),
+ mEglContext(EGL_NO_CONTEXT) {
+ }
+
+ virtual void SetUp() {
+ LOGV("GLTest::SetUp()");
+ mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+ ASSERT_EQ(EGL_SUCCESS, eglGetError());
+ ASSERT_NE(EGL_NO_DISPLAY, mEglDisplay);
+
+ EGLint majorVersion;
+ EGLint minorVersion;
+ EXPECT_TRUE(eglInitialize(mEglDisplay, &majorVersion, &minorVersion));
+ ASSERT_EQ(EGL_SUCCESS, eglGetError());
+ RecordProperty("EglVersionMajor", majorVersion);
+ RecordProperty("EglVersionMajor", minorVersion);
+
+ EGLint numConfigs = 0;
+ EXPECT_TRUE(eglChooseConfig(mEglDisplay, getConfigAttribs(), &mGlConfig,
+ 1, &numConfigs));
+ ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+ char* displaySecsEnv = getenv("GLTEST_DISPLAY_SECS");
+ if (displaySecsEnv != NULL) {
+ mDisplaySecs = atoi(displaySecsEnv);
+ if (mDisplaySecs < 0) {
+ mDisplaySecs = 0;
+ }
+ } else {
+ mDisplaySecs = 0;
+ }
+
+ if (mDisplaySecs > 0) {
+ mComposerClient = new SurfaceComposerClient;
+ ASSERT_EQ(NO_ERROR, mComposerClient->initCheck());
+
+ mSurfaceControl = mComposerClient->createSurface(
+ String8("Test Surface"), 0,
+ getSurfaceWidth(), getSurfaceHeight(),
+ PIXEL_FORMAT_RGB_888, 0);
+
+ ASSERT_TRUE(mSurfaceControl != NULL);
+ ASSERT_TRUE(mSurfaceControl->isValid());
+
+ SurfaceComposerClient::openGlobalTransaction();
+ ASSERT_EQ(NO_ERROR, mSurfaceControl->setLayer(0x7FFFFFFF));
+ ASSERT_EQ(NO_ERROR, mSurfaceControl->show());
+ SurfaceComposerClient::closeGlobalTransaction();
+
+ sp<ANativeWindow> window = mSurfaceControl->getSurface();
+ mEglSurface = eglCreateWindowSurface(mEglDisplay, mGlConfig,
+ window.get(), NULL);
+ } else {
+ EGLint pbufferAttribs[] = {
+ EGL_WIDTH, getSurfaceWidth(),
+ EGL_HEIGHT, getSurfaceHeight(),
+ EGL_NONE };
+
+ mEglSurface = eglCreatePbufferSurface(mEglDisplay, mGlConfig,
+ pbufferAttribs);
+ }
+ ASSERT_EQ(EGL_SUCCESS, eglGetError());
+ ASSERT_NE(EGL_NO_SURFACE, mEglSurface);
+
+ mEglContext = eglCreateContext(mEglDisplay, mGlConfig, EGL_NO_CONTEXT,
+ getContextAttribs());
+ ASSERT_EQ(EGL_SUCCESS, eglGetError());
+ ASSERT_NE(EGL_NO_CONTEXT, mEglContext);
+
+ EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
+ mEglContext));
+ ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+ EGLint w, h;
+ EXPECT_TRUE(eglQuerySurface(mEglDisplay, mEglSurface, EGL_WIDTH, &w));
+ ASSERT_EQ(EGL_SUCCESS, eglGetError());
+ EXPECT_TRUE(eglQuerySurface(mEglDisplay, mEglSurface, EGL_HEIGHT, &h));
+ ASSERT_EQ(EGL_SUCCESS, eglGetError());
+ RecordProperty("EglSurfaceWidth", w);
+ RecordProperty("EglSurfaceHeight", h);
+
+ glViewport(0, 0, w, h);
+ ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+ }
+
+ virtual void TearDown() {
+ // Display the result
+ if (mDisplaySecs > 0 && mEglSurface != EGL_NO_SURFACE) {
+ eglSwapBuffers(mEglDisplay, mEglSurface);
+ sleep(mDisplaySecs);
+ }
+
+ if (mComposerClient != NULL) {
+ mComposerClient->dispose();
+ }
+ if (mEglContext != EGL_NO_CONTEXT) {
+ eglDestroyContext(mEglDisplay, mEglContext);
+ }
+ if (mEglSurface != EGL_NO_SURFACE) {
+ eglDestroySurface(mEglDisplay, mEglSurface);
+ }
+ if (mEglDisplay != EGL_NO_DISPLAY) {
+ eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE,
+ EGL_NO_CONTEXT);
+ eglTerminate(mEglDisplay);
+ }
+ ASSERT_EQ(EGL_SUCCESS, eglGetError());
+ }
+
+ virtual EGLint const* getConfigAttribs() {
+ LOGV("GLTest getConfigAttribs");
+ static EGLint sDefaultConfigAttribs[] = {
+ EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
+ EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+ EGL_RED_SIZE, 8,
+ EGL_GREEN_SIZE, 8,
+ EGL_BLUE_SIZE, 8,
+ EGL_ALPHA_SIZE, 8,
+ EGL_DEPTH_SIZE, 16,
+ EGL_STENCIL_SIZE, 8,
+ EGL_NONE };
+
+ return sDefaultConfigAttribs;
+ }
+
+ virtual EGLint const* getContextAttribs() {
+ static EGLint sDefaultContextAttribs[] = {
+ EGL_CONTEXT_CLIENT_VERSION, 2,
+ EGL_NONE };
+
+ return sDefaultContextAttribs;
+ }
+
+ virtual EGLint getSurfaceWidth() {
+ return 512;
+ }
+
+ virtual EGLint getSurfaceHeight() {
+ return 512;
+ }
+
+ void loadShader(GLenum shaderType, const char* pSource, GLuint* outShader) {
+ GLuint shader = glCreateShader(shaderType);
+ ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+ if (shader) {
+ glShaderSource(shader, 1, &pSource, NULL);
+ ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+ glCompileShader(shader);
+ ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+ GLint compiled = 0;
+ glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
+ ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+ if (!compiled) {
+ GLint infoLen = 0;
+ glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
+ ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+ if (infoLen) {
+ char* buf = (char*) malloc(infoLen);
+ if (buf) {
+ glGetShaderInfoLog(shader, infoLen, NULL, buf);
+ printf("Shader compile log:\n%s\n", buf);
+ free(buf);
+ FAIL();
+ }
+ } else {
+ char* buf = (char*) malloc(0x1000);
+ if (buf) {
+ glGetShaderInfoLog(shader, 0x1000, NULL, buf);
+ printf("Shader compile log:\n%s\n", buf);
+ free(buf);
+ FAIL();
+ }
+ }
+ glDeleteShader(shader);
+ shader = 0;
+ }
+ }
+ ASSERT_TRUE(shader != 0);
+ *outShader = shader;
+ }
+
+ void createProgram(const char* pVertexSource, const char* pFragmentSource,
+ GLuint* outPgm) {
+ GLuint vertexShader, fragmentShader;
+ {
+ SCOPED_TRACE("compiling vertex shader");
+ loadShader(GL_VERTEX_SHADER, pVertexSource, &vertexShader);
+ if (HasFatalFailure()) {
+ return;
+ }
+ }
+ {
+ SCOPED_TRACE("compiling fragment shader");
+ loadShader(GL_FRAGMENT_SHADER, pFragmentSource, &fragmentShader);
+ if (HasFatalFailure()) {
+ return;
+ }
+ }
+
+ GLuint program = glCreateProgram();
+ ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+ if (program) {
+ glAttachShader(program, vertexShader);
+ ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+ glAttachShader(program, fragmentShader);
+ ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+ glLinkProgram(program);
+ GLint linkStatus = GL_FALSE;
+ glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
+ if (linkStatus != GL_TRUE) {
+ GLint bufLength = 0;
+ glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);
+ if (bufLength) {
+ char* buf = (char*) malloc(bufLength);
+ if (buf) {
+ glGetProgramInfoLog(program, bufLength, NULL, buf);
+ printf("Program link log:\n%s\n", buf);
+ free(buf);
+ FAIL();
+ }
+ }
+ glDeleteProgram(program);
+ program = 0;
+ }
+ }
+ glDeleteShader(vertexShader);
+ glDeleteShader(fragmentShader);
+ ASSERT_TRUE(program != 0);
+ *outPgm = program;
+ }
+
+ static int abs(int value) {
+ return value > 0 ? value : -value;
+ }
+
+ ::testing::AssertionResult checkPixel(int x, int y, int r,
+ int g, int b, int a, int tolerance=2) {
+ GLubyte pixel[4];
+ String8 msg;
+ glReadPixels(x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
+ GLenum err = glGetError();
+ if (err != GL_NO_ERROR) {
+ msg += String8::format("error reading pixel: %#x", err);
+ while ((err = glGetError()) != GL_NO_ERROR) {
+ msg += String8::format(", %#x", err);
+ }
+ fprintf(stderr, "pixel check failure: %s\n", msg.string());
+ return ::testing::AssertionFailure(
+ ::testing::Message(msg.string()));
+ }
+ if (r >= 0 && abs(r - int(pixel[0])) > tolerance) {
+ msg += String8::format("r(%d isn't %d)", pixel[0], r);
+ }
+ if (g >= 0 && abs(g - int(pixel[1])) > tolerance) {
+ if (!msg.isEmpty()) {
+ msg += " ";
+ }
+ msg += String8::format("g(%d isn't %d)", pixel[1], g);
+ }
+ if (b >= 0 && abs(b - int(pixel[2])) > tolerance) {
+ if (!msg.isEmpty()) {
+ msg += " ";
+ }
+ msg += String8::format("b(%d isn't %d)", pixel[2], b);
+ }
+ if (a >= 0 && abs(a - int(pixel[3])) > tolerance) {
+ if (!msg.isEmpty()) {
+ msg += " ";
+ }
+ msg += String8::format("a(%d isn't %d)", pixel[3], a);
+ }
+ if (!msg.isEmpty()) {
+ fprintf(stderr, "pixel check failure: %s\n", msg.string());
+ return ::testing::AssertionFailure(
+ ::testing::Message(msg.string()));
+ } else {
+ return ::testing::AssertionSuccess();
+ }
+ }
+
+ int mDisplaySecs;
+ sp<SurfaceComposerClient> mComposerClient;
+ sp<SurfaceControl> mSurfaceControl;
+
+ EGLDisplay mEglDisplay;
+ EGLSurface mEglSurface;
+ EGLContext mEglContext;
+ EGLConfig mGlConfig;
+};
+
+///////////////////////////////////////////////////////////////////////
+// Class for the NON-GL tests
+///////////////////////////////////////////////////////////////////////
class SurfaceMediaSourceTest : public ::testing::Test {
public:
- SurfaceMediaSourceTest( ): mYuvTexWidth(64), mYuvTexHeight(66) { }
- sp<MPEG4Writer> setUpWriter(OMXClient &client );
+ SurfaceMediaSourceTest( ): mYuvTexWidth(176), mYuvTexHeight(144) { }
void oneBufferPass(int width, int height );
+ void oneBufferPassNoFill(int width, int height );
static void fillYV12Buffer(uint8_t* buf, int w, int h, int stride) ;
static void fillYV12BufferRect(uint8_t* buf, int w, int h,
int stride, const android_native_rect_t& rect) ;
@@ -62,10 +363,8 @@
mSMS->setSynchronousMode(true);
mSTC = new SurfaceTextureClient(mSMS);
mANW = mSTC;
-
}
-
virtual void TearDown() {
mSMS.clear();
mSTC.clear();
@@ -78,11 +377,142 @@
sp<SurfaceMediaSource> mSMS;
sp<SurfaceTextureClient> mSTC;
sp<ANativeWindow> mANW;
-
};
+///////////////////////////////////////////////////////////////////////
+// Class for the GL tests
+///////////////////////////////////////////////////////////////////////
+class SurfaceMediaSourceGLTest : public GLTest {
+public:
+
+ SurfaceMediaSourceGLTest( ): mYuvTexWidth(176), mYuvTexHeight(144) { }
+ virtual EGLint const* getConfigAttribs();
+ void oneBufferPassGL(int num = 0);
+ static sp<MediaRecorder> setUpMediaRecorder(int fileDescriptor, int videoSource,
+ int outputFormat, int videoEncoder, int width, int height, int fps);
+protected:
+
+ virtual void SetUp() {
+ LOGV("SMS-GLTest::SetUp()");
+ android::ProcessState::self()->startThreadPool();
+ mSMS = new SurfaceMediaSource(mYuvTexWidth, mYuvTexHeight);
+ mSTC = new SurfaceTextureClient(mSMS);
+ mANW = mSTC;
+
+ // Doing the setup related to the GL Side
+ GLTest::SetUp();
+ }
+
+ virtual void TearDown() {
+ mSMS.clear();
+ mSTC.clear();
+ mANW.clear();
+ GLTest::TearDown();
+ eglDestroySurface(mEglDisplay, mSmsEglSurface);
+ }
+
+ void setUpEGLSurfaceFromMediaRecorder(sp<MediaRecorder>& mr);
+
+ const int mYuvTexWidth;
+ const int mYuvTexHeight;
+
+ sp<SurfaceMediaSource> mSMS;
+ sp<SurfaceTextureClient> mSTC;
+ sp<ANativeWindow> mANW;
+ EGLConfig mSMSGlConfig;
+ EGLSurface mSmsEglSurface;
+};
+
+/////////////////////////////////////////////////////////////////////
+// Methods in SurfaceMediaSourceGLTest
+/////////////////////////////////////////////////////////////////////
+EGLint const* SurfaceMediaSourceGLTest::getConfigAttribs() {
+ LOGV("SurfaceMediaSourceGLTest getConfigAttribs");
+ static EGLint sDefaultConfigAttribs[] = {
+ EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
+ EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+ EGL_RED_SIZE, 8,
+ EGL_GREEN_SIZE, 8,
+ EGL_BLUE_SIZE, 8,
+ EGL_RECORDABLE_ANDROID, EGL_TRUE,
+ EGL_NONE };
+
+ return sDefaultConfigAttribs;
+}
+
+// One pass of dequeuing and queuing a GLBuffer
+void SurfaceMediaSourceGLTest::oneBufferPassGL(int num) {
+ int d = num % 50;
+ float f = 0.2f; // 0.1f * d;
+
+ glClearColor(0, 0.3, 0, 0.6);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ glEnable(GL_SCISSOR_TEST);
+ glScissor(4 + d, 4 + d, 4, 4);
+ glClearColor(1.0 - f, f, f, 1.0);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ glScissor(24 + d, 48 + d, 4, 4);
+ glClearColor(f, 1.0 - f, f, 1.0);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ glScissor(37 + d, 17 + d, 4, 4);
+ glClearColor(f, f, 1.0 - f, 1.0);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ // The following call dequeues and queues the buffer
+ eglSwapBuffers(mEglDisplay, mSmsEglSurface);
+ glDisable(GL_SCISSOR_TEST);
+}
+
+// Set up the MediaRecorder which runs in the same process as mediaserver
+sp<MediaRecorder> SurfaceMediaSourceGLTest::setUpMediaRecorder(int fd, int videoSource,
+ int outputFormat, int videoEncoder, int width, int height, int fps) {
+ sp<MediaRecorder> mr = new MediaRecorder();
+ mr->setVideoSource(videoSource);
+ mr->setOutputFormat(outputFormat);
+ mr->setVideoEncoder(videoEncoder);
+ mr->setOutputFile(fd, 0, 0);
+ mr->setVideoSize(width, height);
+ mr->setVideoFrameRate(fps);
+ mr->prepare();
+ LOGV("Starting MediaRecorder...");
+ CHECK_EQ(OK, mr->start());
+ return mr;
+}
+
+// query the mediarecorder for a surfacemeidasource and create an egl surface with that
+void SurfaceMediaSourceGLTest::setUpEGLSurfaceFromMediaRecorder(sp<MediaRecorder>& mr) {
+ sp<ISurfaceTexture> iST = mr->querySurfaceMediaSourceFromMediaServer();
+ mSTC = new SurfaceTextureClient(iST);
+ mANW = mSTC;
+
+ EGLint numConfigs = 0;
+ EXPECT_TRUE(eglChooseConfig(mEglDisplay, getConfigAttribs(), &mSMSGlConfig,
+ 1, &numConfigs));
+ ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+ LOGV("Native Window = %p, mSTC = %p", mANW.get(), mSTC.get());
+
+ mSmsEglSurface = eglCreateWindowSurface(mEglDisplay, mSMSGlConfig,
+ mANW.get(), NULL);
+ ASSERT_EQ(EGL_SUCCESS, eglGetError());
+ ASSERT_NE(EGL_NO_SURFACE, mSmsEglSurface) ;
+
+ EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mSmsEglSurface, mSmsEglSurface,
+ mEglContext));
+ ASSERT_EQ(EGL_SUCCESS, eglGetError());
+}
+
+
+/////////////////////////////////////////////////////////////////////
+// Methods in SurfaceMediaSourceTest
+/////////////////////////////////////////////////////////////////////
+
+// One pass of dequeuing and queuing the buffer. Fill it in with
+// cpu YV12 buffer
void SurfaceMediaSourceTest::oneBufferPass(int width, int height ) {
- LOGV("One Buffer Pass");
ANativeWindowBuffer* anb;
ASSERT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
ASSERT_TRUE(anb != NULL);
@@ -99,42 +529,16 @@
ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer()));
}
-sp<MPEG4Writer> SurfaceMediaSourceTest::setUpWriter(OMXClient &client ) {
- // Writing to a file
- const char *fileName = "/sdcard/outputSurfEnc.mp4";
- sp<MetaData> enc_meta = new MetaData;
- enc_meta->setInt32(kKeyBitRate, 300000);
- enc_meta->setInt32(kKeyFrameRate, 30);
+// Dequeuing and queuing the buffer without really filling it in.
+void SurfaceMediaSourceTest::oneBufferPassNoFill(int width, int height ) {
+ ANativeWindowBuffer* anb;
+ ASSERT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
+ ASSERT_TRUE(anb != NULL);
- enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4);
-
- sp<MetaData> meta = mSMS->getFormat();
-
- int32_t width, height, stride, sliceHeight, colorFormat;
- CHECK(meta->findInt32(kKeyWidth, &width));
- CHECK(meta->findInt32(kKeyHeight, &height));
- CHECK(meta->findInt32(kKeyStride, &stride));
- CHECK(meta->findInt32(kKeySliceHeight, &sliceHeight));
- CHECK(meta->findInt32(kKeyColorFormat, &colorFormat));
-
- enc_meta->setInt32(kKeyWidth, width);
- enc_meta->setInt32(kKeyHeight, height);
- enc_meta->setInt32(kKeyIFramesInterval, 1);
- enc_meta->setInt32(kKeyStride, stride);
- enc_meta->setInt32(kKeySliceHeight, sliceHeight);
- // TODO: overwriting the colorformat since the format set by GRAlloc
- // could be wrong or not be read by OMX
- enc_meta->setInt32(kKeyColorFormat, OMX_COLOR_FormatYUV420Planar);
-
-
- sp<MediaSource> encoder =
- OMXCodec::Create(
- client.interface(), enc_meta, true /* createEncoder */, mSMS);
-
- sp<MPEG4Writer> writer = new MPEG4Writer(fileName);
- writer->addSource(encoder);
-
- return writer;
+ sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
+ // ASSERT_EQ(NO_ERROR, mANW->lockBuffer(mANW.get(), buf->getNativeBuffer()));
+ // We do not fill the buffer in. Just queue it back.
+ ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer()));
}
// Fill a YV12 buffer with a multi-colored checkerboard pattern
@@ -216,46 +620,53 @@
return OK;
}
};
-
///////////////////////////////////////////////////////////////////
// TESTS
+// SurfaceMediaSourceTest class contains tests that fill the buffers
+// using the cpu calls
+// SurfaceMediaSourceGLTest class contains tests that fill the buffers
+// using the GL calls.
+// TODO: None of the tests actually verify the encoded images.. so at this point,
+// these are mostly functionality tests + visual inspection
+//////////////////////////////////////////////////////////////////////
+
// Just pass one buffer from the native_window to the SurfaceMediaSource
-TEST_F(SurfaceMediaSourceTest, EncodingFromCpuFilledYV12BufferNpotOneBufferPass) {
+// Dummy Encoder
+static int testId = 1;
+TEST_F(SurfaceMediaSourceTest, DISABLED_DummyEncodingFromCpuFilledYV12BufferNpotOneBufferPass) {
+ LOGV("Test # %d", testId++);
LOGV("Testing OneBufferPass ******************************");
- ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
- 0, 0, HAL_PIXEL_FORMAT_YV12));
- ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
- GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
-
+ ASSERT_EQ(NO_ERROR, native_window_set_buffers_format(mANW.get(),
+ HAL_PIXEL_FORMAT_YV12));
oneBufferPass(mYuvTexWidth, mYuvTexHeight);
}
// Pass the buffer with the wrong height and weight and should not be accepted
-TEST_F(SurfaceMediaSourceTest, EncodingFromCpuFilledYV12BufferNpotWrongSizeBufferPass) {
+// Dummy Encoder
+TEST_F(SurfaceMediaSourceTest, DISABLED_DummyEncodingFromCpuFilledYV12BufferNpotWrongSizeBufferPass) {
+ LOGV("Test # %d", testId++);
LOGV("Testing Wrong size BufferPass ******************************");
// setting the client side buffer size different than the server size
- ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
- 10, 10, HAL_PIXEL_FORMAT_YV12));
- ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
- GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
+ ASSERT_EQ(NO_ERROR, native_window_set_buffers_dimensions(mANW.get(),
+ 10, 10));
+ ASSERT_EQ(NO_ERROR, native_window_set_buffers_format(mANW.get(),
+ HAL_PIXEL_FORMAT_YV12));
ANativeWindowBuffer* anb;
- // make sure we get an error back when dequeuing!
+ // Note: make sure we get an ERROR back when dequeuing!
ASSERT_NE(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
}
-
// pass multiple buffers from the native_window the SurfaceMediaSource
-// A dummy writer is used to simulate actual MPEG4Writer
-TEST_F(SurfaceMediaSourceTest, EncodingFromCpuFilledYV12BufferNpotMultiBufferPass) {
+// Dummy Encoder
+TEST_F(SurfaceMediaSourceTest, DISABLED_DummyEncodingFromCpuFilledYV12BufferNpotMultiBufferPass) {
+ LOGV("Test # %d", testId++);
LOGV("Testing MultiBufferPass, Dummy Recorder *********************");
- ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
- 0, 0, HAL_PIXEL_FORMAT_YV12));
- ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
- GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
+ ASSERT_EQ(NO_ERROR, native_window_set_buffers_format(mANW.get(),
+ HAL_PIXEL_FORMAT_YV12));
SimpleDummyRecorder writer(mSMS);
writer.start();
@@ -272,14 +683,13 @@
}
// Delayed pass of multiple buffers from the native_window the SurfaceMediaSource
-// A dummy writer is used to simulate actual MPEG4Writer
-TEST_F(SurfaceMediaSourceTest, EncodingFromCpuFilledYV12BufferNpotMultiBufferPassLag) {
+// Dummy Encoder
+TEST_F(SurfaceMediaSourceTest, DISABLED_DummyLagEncodingFromCpuFilledYV12BufferNpotMultiBufferPass) {
+ LOGV("Test # %d", testId++);
LOGV("Testing MultiBufferPass, Dummy Recorder Lagging **************");
- ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
- 0, 0, HAL_PIXEL_FORMAT_YV12));
- ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
- GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
+ ASSERT_EQ(NO_ERROR, native_window_set_buffers_format(mANW.get(),
+ HAL_PIXEL_FORMAT_YV12));
SimpleDummyRecorder writer(mSMS);
writer.start();
@@ -299,12 +709,11 @@
// pass multiple buffers from the native_window the SurfaceMediaSource
// A dummy writer (MULTITHREADED) is used to simulate actual MPEG4Writer
-TEST_F(SurfaceMediaSourceTest, EncodingFromCpuFilledYV12BufferNpotMultiBufferPassThreaded) {
+TEST_F(SurfaceMediaSourceTest, DISABLED_DummyThreadedEncodingFromCpuFilledYV12BufferNpotMultiBufferPass) {
+ LOGV("Test # %d", testId++);
LOGV("Testing MultiBufferPass, Dummy Recorder Multi-Threaded **********");
- ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
- 0, 0, HAL_PIXEL_FORMAT_YV12));
- ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
- GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
+ ASSERT_EQ(NO_ERROR, native_window_set_buffers_format(mANW.get(),
+ HAL_PIXEL_FORMAT_YV12));
DummyRecorder writer(mSMS);
writer.start();
@@ -318,32 +727,210 @@
writer.stop();
}
-// Test to examine the actual encoding. Temporarily disabled till the
-// colorformat and encoding from GRAlloc data is resolved
-TEST_F(SurfaceMediaSourceTest, DISABLED_EncodingFromCpuFilledYV12BufferNpotWrite) {
- LOGV("Testing the whole pipeline with actual Recorder");
- ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
- 0, 0, HAL_PIXEL_FORMAT_YV12));
- ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
- GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
- OMXClient client;
- CHECK_EQ(OK, client.connect());
+// Test to examine actual encoding using mediarecorder
+// We use the mediaserver to create a mediarecorder and send
+// it back to us. So SurfaceMediaSource lives in the same process
+// as the mediaserver.
+// Very close to the actual camera, except that the
+// buffers are filled and queueud by the CPU instead of GL.
+TEST_F(SurfaceMediaSourceTest, DISABLED_EncodingFromCpuYV12BufferNpotWriteMediaServer) {
+ LOGV("Test # %d", testId++);
+ LOGV("************** Testing the whole pipeline with actual MediaRecorder ***********");
+ LOGV("************** SurfaceMediaSource is same process as mediaserver ***********");
- sp<MPEG4Writer> writer = setUpWriter(client);
- int64_t start = systemTime();
- CHECK_EQ(OK, writer->start());
+ const char *fileName = "/sdcard/outputSurfEncMSource.mp4";
+ int fd = open(fileName, O_RDWR | O_CREAT, 0744);
+ if (fd < 0) {
+ LOGE("ERROR: Could not open the the file %s, fd = %d !!", fileName, fd);
+ }
+ CHECK(fd >= 0);
+
+ sp<MediaRecorder> mr = SurfaceMediaSourceGLTest::setUpMediaRecorder(fd,
+ VIDEO_SOURCE_GRALLOC_BUFFER,
+ OUTPUT_FORMAT_MPEG_4, VIDEO_ENCODER_H264, mYuvTexWidth,
+ mYuvTexHeight, 30);
+ // get the reference to the surfacemediasource living in
+ // mediaserver that is created by stagefrightrecorder
+ sp<ISurfaceTexture> iST = mr->querySurfaceMediaSourceFromMediaServer();
+ mSTC = new SurfaceTextureClient(iST);
+ mANW = mSTC;
+ ASSERT_EQ(NO_ERROR, native_window_api_connect(mANW.get(), NATIVE_WINDOW_API_CPU));
+ ASSERT_EQ(NO_ERROR, native_window_set_buffers_format(mANW.get(),
+ HAL_PIXEL_FORMAT_YV12));
int32_t nFramesCount = 0;
while (nFramesCount <= 300) {
- oneBufferPass(mYuvTexWidth, mYuvTexHeight);
+ oneBufferPassNoFill(mYuvTexWidth, mYuvTexHeight);
nFramesCount++;
+ LOGV("framesCount = %d", nFramesCount);
}
- CHECK_EQ(OK, writer->stop());
- writer.clear();
- int64_t end = systemTime();
- client.disconnect();
+ ASSERT_EQ(NO_ERROR, native_window_api_disconnect(mANW.get(), NATIVE_WINDOW_API_CPU));
+ LOGV("Stopping MediaRecorder...");
+ CHECK_EQ(OK, mr->stop());
+ mr.clear();
+ close(fd);
}
+//////////////////////////////////////////////////////////////////////
+// GL tests
+/////////////////////////////////////////////////////////////////////
+// Test to examine whether we can choose the Recordable Android GLConfig
+// DummyRecorder used- no real encoding here
+TEST_F(SurfaceMediaSourceGLTest, ChooseAndroidRecordableEGLConfigDummyWrite) {
+ LOGV("Test # %d", testId++);
+ LOGV("Test to verify creating a surface w/ right config *********");
+
+ mSMS = new SurfaceMediaSource(mYuvTexWidth, mYuvTexHeight);
+ mSTC = new SurfaceTextureClient(mSMS);
+ mANW = mSTC;
+
+ DummyRecorder writer(mSMS);
+ writer.start();
+
+ EGLint numConfigs = 0;
+ EXPECT_TRUE(eglChooseConfig(mEglDisplay, getConfigAttribs(), &mSMSGlConfig,
+ 1, &numConfigs));
+ ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+ mSmsEglSurface = eglCreateWindowSurface(mEglDisplay, mSMSGlConfig,
+ mANW.get(), NULL);
+ ASSERT_EQ(EGL_SUCCESS, eglGetError());
+ ASSERT_NE(EGL_NO_SURFACE, mSmsEglSurface) ;
+
+ EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mSmsEglSurface, mSmsEglSurface,
+ mEglContext));
+ ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+ int32_t nFramesCount = 0;
+ while (nFramesCount <= 300) {
+ oneBufferPassGL();
+ nFramesCount++;
+ LOGV("framesCount = %d", nFramesCount);
+ }
+
+ ASSERT_EQ(NO_ERROR, native_window_api_disconnect(mANW.get(), NATIVE_WINDOW_API_EGL));
+ writer.stop();
+}
+// Test to examine whether we can render GL buffers in to the surface
+// created with the native window handle
+TEST_F(SurfaceMediaSourceGLTest, RenderingToRecordableEGLSurfaceWorks) {
+ LOGV("Test # %d", testId++);
+ LOGV("RenderingToRecordableEGLSurfaceWorks *********************");
+ // Do the producer side of things
+ glClearColor(0.6, 0.6, 0.6, 0.6);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ glEnable(GL_SCISSOR_TEST);
+ glScissor(4, 4, 4, 4);
+ glClearColor(1.0, 0.0, 0.0, 1.0);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ glScissor(24, 48, 4, 4);
+ glClearColor(0.0, 1.0, 0.0, 1.0);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ glScissor(37, 17, 4, 4);
+ glClearColor(0.0, 0.0, 1.0, 1.0);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ EXPECT_TRUE(checkPixel( 0, 0, 153, 153, 153, 153));
+ EXPECT_TRUE(checkPixel(63, 0, 153, 153, 153, 153));
+ EXPECT_TRUE(checkPixel(63, 63, 153, 153, 153, 153));
+ EXPECT_TRUE(checkPixel( 0, 63, 153, 153, 153, 153));
+
+ EXPECT_TRUE(checkPixel( 4, 7, 255, 0, 0, 255));
+ EXPECT_TRUE(checkPixel(25, 51, 0, 255, 0, 255));
+ EXPECT_TRUE(checkPixel(40, 19, 0, 0, 255, 255));
+ EXPECT_TRUE(checkPixel(29, 51, 153, 153, 153, 153));
+ EXPECT_TRUE(checkPixel( 5, 32, 153, 153, 153, 153));
+ EXPECT_TRUE(checkPixel(13, 8, 153, 153, 153, 153));
+ EXPECT_TRUE(checkPixel(46, 3, 153, 153, 153, 153));
+ EXPECT_TRUE(checkPixel(30, 33, 153, 153, 153, 153));
+ EXPECT_TRUE(checkPixel( 6, 52, 153, 153, 153, 153));
+ EXPECT_TRUE(checkPixel(55, 33, 153, 153, 153, 153));
+ EXPECT_TRUE(checkPixel(16, 29, 153, 153, 153, 153));
+ EXPECT_TRUE(checkPixel( 1, 30, 153, 153, 153, 153));
+ EXPECT_TRUE(checkPixel(41, 37, 153, 153, 153, 153));
+ EXPECT_TRUE(checkPixel(46, 29, 153, 153, 153, 153));
+ EXPECT_TRUE(checkPixel(15, 25, 153, 153, 153, 153));
+ EXPECT_TRUE(checkPixel( 3, 52, 153, 153, 153, 153));
+}
+
+// Test to examine the actual encoding with GL buffers
+// Actual encoder, Actual GL Buffers Filled SurfaceMediaSource
+// The same pattern is rendered every frame
+TEST_F(SurfaceMediaSourceGLTest, EncodingFromGLRgbaSameImageEachBufNpotWrite) {
+ LOGV("Test # %d", testId++);
+ LOGV("************** Testing the whole pipeline with actual Recorder ***********");
+ LOGV("************** GL Filling the buffers ***********");
+ // Note: No need to set the colorformat for the buffers. The colorformat is
+ // in the GRAlloc buffers itself.
+
+ const char *fileName = "/sdcard/outputSurfEncMSourceGL.mp4";
+ int fd = open(fileName, O_RDWR | O_CREAT, 0744);
+ if (fd < 0) {
+ LOGE("ERROR: Could not open the the file %s, fd = %d !!", fileName, fd);
+ }
+ CHECK(fd >= 0);
+
+ sp<MediaRecorder> mr = setUpMediaRecorder(fd, VIDEO_SOURCE_GRALLOC_BUFFER,
+ OUTPUT_FORMAT_MPEG_4, VIDEO_ENCODER_H264, mYuvTexWidth, mYuvTexHeight, 30);
+
+ // get the reference to the surfacemediasource living in
+ // mediaserver that is created by stagefrightrecorder
+ setUpEGLSurfaceFromMediaRecorder(mr);
+
+ int32_t nFramesCount = 0;
+ while (nFramesCount <= 300) {
+ oneBufferPassGL();
+ nFramesCount++;
+ LOGV("framesCount = %d", nFramesCount);
+ }
+
+ ASSERT_EQ(NO_ERROR, native_window_api_disconnect(mANW.get(), NATIVE_WINDOW_API_EGL));
+ LOGV("Stopping MediaRecorder...");
+ CHECK_EQ(OK, mr->stop());
+ mr.clear();
+ close(fd);
+}
+
+// Test to examine the actual encoding from the GL Buffers
+// Actual encoder, Actual GL Buffers Filled SurfaceMediaSource
+// A different pattern is rendered every frame
+TEST_F(SurfaceMediaSourceGLTest, EncodingFromGLRgbaDiffImageEachBufNpotWrite) {
+ LOGV("Test # %d", testId++);
+ LOGV("************** Testing the whole pipeline with actual Recorder ***********");
+ LOGV("************** Diff GL Filling the buffers ***********");
+ // Note: No need to set the colorformat for the buffers. The colorformat is
+ // in the GRAlloc buffers itself.
+
+ const char *fileName = "/sdcard/outputSurfEncMSourceGLDiff.mp4";
+ int fd = open(fileName, O_RDWR | O_CREAT, 0744);
+ if (fd < 0) {
+ LOGE("ERROR: Could not open the the file %s, fd = %d !!", fileName, fd);
+ }
+ CHECK(fd >= 0);
+
+ sp<MediaRecorder> mr = setUpMediaRecorder(fd, VIDEO_SOURCE_GRALLOC_BUFFER,
+ OUTPUT_FORMAT_MPEG_4, VIDEO_ENCODER_H264, mYuvTexWidth, mYuvTexHeight, 30);
+
+ // get the reference to the surfacemediasource living in
+ // mediaserver that is created by stagefrightrecorder
+ setUpEGLSurfaceFromMediaRecorder(mr);
+
+ int32_t nFramesCount = 0;
+ while (nFramesCount <= 300) {
+ oneBufferPassGL(nFramesCount);
+ nFramesCount++;
+ LOGV("framesCount = %d", nFramesCount);
+ }
+
+ ASSERT_EQ(NO_ERROR, native_window_api_disconnect(mANW.get(), NATIVE_WINDOW_API_EGL));
+ LOGV("Stopping MediaRecorder...");
+ CHECK_EQ(OK, mr->stop());
+ mr.clear();
+ close(fd);
+}
} // namespace android
diff --git a/opengl/java/android/opengl/GLUtils.java b/opengl/java/android/opengl/GLUtils.java
index f30a4cd4..125c56e 100644
--- a/opengl/java/android/opengl/GLUtils.java
+++ b/opengl/java/android/opengl/GLUtils.java
@@ -16,9 +16,11 @@
package android.opengl;
-import javax.microedition.khronos.opengles.GL10;
import android.graphics.Bitmap;
+import javax.microedition.khronos.egl.EGL10;
+import javax.microedition.khronos.egl.EGL11;
+
/**
*
* Utility class to help bridging OpenGL ES and Android APIs.
@@ -222,6 +224,51 @@
}
}
+ /**
+ * Return a string for the EGL error code, or the hex representation
+ * if the error is unknown.
+ *
+ * @param error The EGL error to convert into a String.
+ *
+ * @return An error string corresponding to the EGL error code.
+ */
+ public static String getEGLErrorString(int error) {
+ switch (error) {
+ case EGL10.EGL_SUCCESS:
+ return "EGL_SUCCESS";
+ case EGL10.EGL_NOT_INITIALIZED:
+ return "EGL_NOT_INITIALIZED";
+ case EGL10.EGL_BAD_ACCESS:
+ return "EGL_BAD_ACCESS";
+ case EGL10.EGL_BAD_ALLOC:
+ return "EGL_BAD_ALLOC";
+ case EGL10.EGL_BAD_ATTRIBUTE:
+ return "EGL_BAD_ATTRIBUTE";
+ case EGL10.EGL_BAD_CONFIG:
+ return "EGL_BAD_CONFIG";
+ case EGL10.EGL_BAD_CONTEXT:
+ return "EGL_BAD_CONTEXT";
+ case EGL10.EGL_BAD_CURRENT_SURFACE:
+ return "EGL_BAD_CURRENT_SURFACE";
+ case EGL10.EGL_BAD_DISPLAY:
+ return "EGL_BAD_DISPLAY";
+ case EGL10.EGL_BAD_MATCH:
+ return "EGL_BAD_MATCH";
+ case EGL10.EGL_BAD_NATIVE_PIXMAP:
+ return "EGL_BAD_NATIVE_PIXMAP";
+ case EGL10.EGL_BAD_NATIVE_WINDOW:
+ return "EGL_BAD_NATIVE_WINDOW";
+ case EGL10.EGL_BAD_PARAMETER:
+ return "EGL_BAD_PARAMETER";
+ case EGL10.EGL_BAD_SURFACE:
+ return "EGL_BAD_SURFACE";
+ case EGL11.EGL_CONTEXT_LOST:
+ return "EGL_CONTEXT_LOST";
+ default:
+ return "0x" + Integer.toHexString(error);
+ }
+ }
+
native private static void nativeClassInit();
native private static int native_getInternalFormat(Bitmap bitmap);
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_notify_alarm.png b/packages/SystemUI/res/drawable-hdpi/stat_notify_alarm.png
index ddbd3d7..31c8be7 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_notify_alarm.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_notify_alarm.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_notify_alarm.png b/packages/SystemUI/res/drawable-mdpi/stat_notify_alarm.png
index 364cf75..739f9a6 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_notify_alarm.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_notify_alarm.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_notify_alarm.png b/packages/SystemUI/res/drawable-xhdpi/stat_notify_alarm.png
new file mode 100644
index 0000000..7cad385
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_notify_alarm.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_notify_more.png b/packages/SystemUI/res/drawable-xhdpi/stat_notify_more.png
new file mode 100644
index 0000000..16bf510
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_notify_more.png
Binary files differ
diff --git a/packages/SystemUI/res/values-xhdpi/dimens.xml b/packages/SystemUI/res/values-xhdpi/dimens.xml
new file mode 100644
index 0000000..aa75c20
--- /dev/null
+++ b/packages/SystemUI/res/values-xhdpi/dimens.xml
@@ -0,0 +1,27 @@
+<?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.
+*/
+-->
+<resources>
+ <!-- thickness (height) of each notification row, including any separators or padding -->
+ <!-- note: this is the same value as in values/dimens.xml; the value is overridden in
+ values-hdpi/dimens.xml and so we need to re-assert the general value here -->
+ <dimen name="notification_height">65dp</dimen>
+
+ <!-- thickness (height) of dividers between each notification row -->
+ <!-- same as in values/dimens.xml; see note at notification_height -->
+ <dimen name="notification_divider_height">1dp</dimen>
+</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
index e1231a5..049a284 100644
--- a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
+++ b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
@@ -16,41 +16,65 @@
package com.android.systemui;
-import java.io.IOException;
-
+import android.app.ActivityManager;
import android.app.WallpaperManager;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.Region.Op;
-import android.graphics.drawable.Drawable;
-import android.os.Handler;
+import android.opengl.GLUtils;
+import android.renderscript.Matrix4f;
import android.service.wallpaper.WallpaperService;
import android.util.Log;
-import android.util.Slog;
+import android.view.Display;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
-import android.content.Context;
-import android.content.IntentFilter;
-import android.content.Intent;
-import android.content.BroadcastReceiver;
+import android.view.WindowManager;
+
+import javax.microedition.khronos.egl.EGL10;
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.egl.EGLContext;
+import javax.microedition.khronos.egl.EGLDisplay;
+import javax.microedition.khronos.egl.EGLSurface;
+import javax.microedition.khronos.opengles.GL;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.FloatBuffer;
+
+import static android.opengl.GLES20.*;
+import static javax.microedition.khronos.egl.EGL10.*;
/**
* Default built-in wallpaper that simply shows a static image.
*/
+@SuppressWarnings({"UnusedDeclaration"})
public class ImageWallpaper extends WallpaperService {
private static final String TAG = "ImageWallpaper";
+ private static final String GL_LOG_TAG = "ImageWallpaperGL";
private static final boolean DEBUG = false;
static final boolean FIXED_SIZED_SURFACE = true;
+ static final boolean USE_OPENGL = true;
WallpaperManager mWallpaperManager;
- private Handler mHandler;
+
+ boolean mIsHwAccelerated;
@Override
public void onCreate() {
super.onCreate();
mWallpaperManager = (WallpaperManager) getSystemService(WALLPAPER_SERVICE);
- mHandler = new Handler();
+
+ //noinspection PointlessBooleanExpression,ConstantConditions
+ if (FIXED_SIZED_SURFACE && USE_OPENGL) {
+ WindowManager windowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
+ Display display = windowManager.getDefaultDisplay();
+ mIsHwAccelerated = ActivityManager.isHighEndGfx(display);
+ }
}
public Engine onCreateEngine() {
@@ -58,9 +82,16 @@
}
class DrawableEngine extends Engine {
- private final Object mLock = new Object();
+ static final int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
+ static final int EGL_OPENGL_ES2_BIT = 4;
+
+ private final Object mLock = new Object[0];
+
+ // TODO: Not currently used, keeping around until we know we don't need it
+ @SuppressWarnings({"UnusedDeclaration"})
private WallpaperObserver mReceiver;
- Drawable mBackground;
+
+ Bitmap mBackground;
int mBackgroundWidth = -1, mBackgroundHeight = -1;
float mXOffset;
float mYOffset;
@@ -71,6 +102,35 @@
int mLastXTranslation;
int mLastYTranslation;
+ private EGL10 mEgl;
+ private EGLDisplay mEglDisplay;
+ private EGLConfig mEglConfig;
+ private EGLContext mEglContext;
+ private EGLSurface mEglSurface;
+ private GL mGL;
+
+ private static final String sSimpleVS =
+ "attribute vec4 position;\n" +
+ "attribute vec2 texCoords;\n" +
+ "varying vec2 outTexCoords;\n" +
+ "uniform mat4 projection;\n" +
+ "\nvoid main(void) {\n" +
+ " outTexCoords = texCoords;\n" +
+ " gl_Position = projection * position;\n" +
+ "}\n\n";
+ private static final String sSimpleFS =
+ "precision mediump float;\n\n" +
+ "varying vec2 outTexCoords;\n" +
+ "uniform sampler2D texture;\n" +
+ "\nvoid main(void) {\n" +
+ " gl_FragColor = texture2D(texture, outTexCoords);\n" +
+ "}\n\n";
+
+ private static final int FLOAT_SIZE_BYTES = 4;
+ private static final int TRIANGLE_VERTICES_DATA_STRIDE_BYTES = 5 * FLOAT_SIZE_BYTES;
+ private static final int TRIANGLE_VERTICES_DATA_POS_OFFSET = 0;
+ private static final int TRIANGLE_VERTICES_DATA_UV_OFFSET = 3;
+
class WallpaperObserver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
if (DEBUG) {
@@ -94,7 +154,7 @@
super.onCreate(surfaceHolder);
- // Don't need this currently because the wallpaper service
+ // TODO: Don't need this currently because the wallpaper service
// will restart the image wallpaper whenever the image changes.
//IntentFilter filter = new IntentFilter(Intent.ACTION_WALLPAPER_CHANGED);
//mReceiver = new WallpaperObserver();
@@ -221,8 +281,7 @@
int yPixels = availh < 0 ? (int)(availh * mYOffset + .5f) : (availh / 2);
mOffsetsChanged = false;
- if (!mRedrawNeeded
- && xPixels == mLastXTranslation && yPixels == mLastYTranslation) {
+ if (!mRedrawNeeded && xPixels == mLastXTranslation && yPixels == mLastYTranslation) {
if (DEBUG) {
Log.d(TAG, "Suppressed drawFrame since the image has not "
+ "actually moved an integral number of pixels.");
@@ -240,27 +299,10 @@
updateWallpaperLocked();
}
- //Slog.i(TAG, "************** DRAWING WALLAPER ******************");
- Canvas c = sh.lockCanvas();
- if (c != null) {
- try {
- if (DEBUG) {
- Log.d(TAG, "Redrawing: xPixels=" + xPixels + ", yPixels=" + yPixels);
- }
-
- c.translate(xPixels, yPixels);
- if (availw < 0 || availh < 0) {
- c.save(Canvas.CLIP_SAVE_FLAG);
- c.clipRect(0, 0, mBackgroundWidth, mBackgroundHeight, Op.DIFFERENCE);
- c.drawColor(0xff000000);
- c.restore();
- }
- if (mBackground != null) {
- mBackground.draw(c);
- }
- } finally {
- sh.unlockCanvasAndPost(c);
- }
+ if (mIsHwAccelerated) {
+ drawWallpaperWithOpenGL(sh, availw, availh, xPixels, yPixels);
+ } else {
+ drawWallpaperWithCanvas(sh, availw, availh, xPixels, yPixels);
}
if (FIXED_SIZED_SURFACE) {
@@ -274,15 +316,15 @@
}
void updateWallpaperLocked() {
- //Slog.i(TAG, "************** LOADING WALLAPER ******************");
Throwable exception = null;
try {
- mBackground = mWallpaperManager.getFastDrawable();
+ mBackground = mWallpaperManager.getBitmap();
} catch (RuntimeException e) {
exception = e;
} catch (OutOfMemoryError e) {
exception = e;
}
+
if (exception != null) {
mBackground = null;
// Note that if we do fail at this, and the default wallpaper can't
@@ -296,8 +338,277 @@
Log.w(TAG, "Unable reset to default wallpaper!", ex);
}
}
- mBackgroundWidth = mBackground != null ? mBackground.getIntrinsicWidth() : 0;
- mBackgroundHeight = mBackground != null ? mBackground.getIntrinsicHeight() : 0;
+
+ mBackgroundWidth = mBackground != null ? mBackground.getWidth() : 0;
+ mBackgroundHeight = mBackground != null ? mBackground.getHeight() : 0;
+ }
+
+ private void drawWallpaperWithCanvas(SurfaceHolder sh, int w, int h, int x, int y) {
+ Canvas c = sh.lockCanvas();
+ if (c != null) {
+ try {
+ if (DEBUG) {
+ Log.d(TAG, "Redrawing: x=" + x + ", y=" + y);
+ }
+
+ c.translate(x, y);
+ if (w < 0 || h < 0) {
+ c.save(Canvas.CLIP_SAVE_FLAG);
+ c.clipRect(0, 0, mBackgroundWidth, mBackgroundHeight, Op.DIFFERENCE);
+ c.drawColor(0xff000000);
+ c.restore();
+ }
+ if (mBackground != null) {
+ c.drawBitmap(mBackground, 0, 0, null);
+ }
+ } finally {
+ sh.unlockCanvasAndPost(c);
+ }
+ }
+ }
+
+ private void drawWallpaperWithOpenGL(SurfaceHolder sh, int w, int h, int left, int top) {
+ initGL(sh);
+
+ final float right = left + mBackgroundWidth;
+ final float bottom = top + mBackgroundHeight;
+
+ final Rect frame = sh.getSurfaceFrame();
+
+ final Matrix4f ortho = new Matrix4f();
+ ortho.loadOrtho(0.0f, frame.width(), frame.height(), 0.0f, -1.0f, 1.0f);
+
+ final FloatBuffer triangleVertices = createMesh(left, top, right, bottom);
+
+ final int texture = loadTexture(mBackground);
+ final int program = buildProgram(sSimpleVS, sSimpleFS);
+
+ final int attribPosition = glGetAttribLocation(program, "position");
+ final int attribTexCoords = glGetAttribLocation(program, "texCoords");
+ final int uniformTexture = glGetUniformLocation(program, "texture");
+ final int uniformProjection = glGetUniformLocation(program, "projection");
+
+ checkGlError();
+
+ glViewport(0, 0, frame.width(), frame.height());
+ glBindTexture(GL_TEXTURE_2D, texture);
+
+ glUseProgram(program);
+ glEnableVertexAttribArray(attribPosition);
+ glEnableVertexAttribArray(attribTexCoords);
+ glUniform1i(uniformTexture, 0);
+ glUniformMatrix4fv(uniformProjection, 1, false, ortho.getArray(), 0);
+
+ checkGlError();
+
+ if (w < 0 || h < 0) {
+ glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+ glClear(GL_COLOR_BUFFER_BIT);
+ }
+
+ // drawQuad
+ triangleVertices.position(TRIANGLE_VERTICES_DATA_POS_OFFSET);
+ glVertexAttribPointer(attribPosition, 3, GL_FLOAT, false,
+ TRIANGLE_VERTICES_DATA_STRIDE_BYTES, triangleVertices);
+
+ triangleVertices.position(TRIANGLE_VERTICES_DATA_UV_OFFSET);
+ glVertexAttribPointer(attribTexCoords, 3, GL_FLOAT, false,
+ TRIANGLE_VERTICES_DATA_STRIDE_BYTES, triangleVertices);
+
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+
+ if (!mEgl.eglSwapBuffers(mEglDisplay, mEglSurface)) {
+ throw new RuntimeException("Cannot swap buffers");
+ }
+ checkEglError();
+
+ finishGL();
+ }
+
+ private FloatBuffer createMesh(int left, int top, float right, float bottom) {
+ final float[] verticesData = {
+ // X, Y, Z, U, V
+ left, bottom, 0.0f, 0.0f, 1.0f,
+ right, bottom, 0.0f, 1.0f, 1.0f,
+ left, top, 0.0f, 0.0f, 0.0f,
+ right, top, 0.0f, 1.0f, 0.0f,
+ };
+
+ final int bytes = verticesData.length * FLOAT_SIZE_BYTES;
+ final FloatBuffer triangleVertices = ByteBuffer.allocateDirect(bytes).order(
+ ByteOrder.nativeOrder()).asFloatBuffer();
+ triangleVertices.put(verticesData).position(0);
+ return triangleVertices;
+ }
+
+ private int loadTexture(Bitmap bitmap) {
+ int[] textures = new int[1];
+
+ glActiveTexture(GL_TEXTURE0);
+ glGenTextures(1, textures, 0);
+ checkGlError();
+
+ int texture = textures[0];
+ glBindTexture(GL_TEXTURE_2D, texture);
+ checkGlError();
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ GLUtils.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bitmap, GL_UNSIGNED_BYTE, 0);
+ checkGlError();
+
+ bitmap.recycle();
+
+ return texture;
+ }
+
+ private int buildProgram(String vertex, String fragment) {
+ int vertexShader = buildShader(vertex, GL_VERTEX_SHADER);
+ if (vertexShader == 0) return 0;
+
+ int fragmentShader = buildShader(fragment, GL_FRAGMENT_SHADER);
+ if (fragmentShader == 0) return 0;
+
+ int program = glCreateProgram();
+ glAttachShader(program, vertexShader);
+ checkGlError();
+
+ glAttachShader(program, fragmentShader);
+ checkGlError();
+
+ glLinkProgram(program);
+ checkGlError();
+
+ int[] status = new int[1];
+ glGetProgramiv(program, GL_LINK_STATUS, status, 0);
+ if (status[0] != GL_TRUE) {
+ String error = glGetProgramInfoLog(program);
+ Log.d(GL_LOG_TAG, "Error while linking program:\n" + error);
+ glDeleteShader(vertexShader);
+ glDeleteShader(fragmentShader);
+ glDeleteProgram(program);
+ return 0;
+ }
+
+ return program;
+ }
+
+ private int buildShader(String source, int type) {
+ int shader = glCreateShader(type);
+
+ glShaderSource(shader, source);
+ checkGlError();
+
+ glCompileShader(shader);
+ checkGlError();
+
+ int[] status = new int[1];
+ glGetShaderiv(shader, GL_COMPILE_STATUS, status, 0);
+ if (status[0] != GL_TRUE) {
+ String error = glGetShaderInfoLog(shader);
+ Log.d(GL_LOG_TAG, "Error while compiling shader:\n" + error);
+ glDeleteShader(shader);
+ return 0;
+ }
+
+ return shader;
+ }
+
+ private void checkEglError() {
+ int error = mEgl.eglGetError();
+ if (error != EGL_SUCCESS) {
+ Log.w(GL_LOG_TAG, "EGL error = " + GLUtils.getEGLErrorString(error));
+ }
+ }
+
+ private void checkGlError() {
+ int error = glGetError();
+ if (error != GL_NO_ERROR) {
+ Log.w(GL_LOG_TAG, "GL error = 0x" + Integer.toHexString(error), new Throwable());
+ }
+ }
+
+ private void finishGL() {
+ mEgl.eglDestroyContext(mEglDisplay, mEglContext);
+ mEgl.eglDestroySurface(mEglDisplay, mEglSurface);
+ }
+
+ private void initGL(SurfaceHolder surfaceHolder) {
+ mEgl = (EGL10) EGLContext.getEGL();
+
+ mEglDisplay = mEgl.eglGetDisplay(EGL_DEFAULT_DISPLAY);
+ if (mEglDisplay == EGL_NO_DISPLAY) {
+ throw new RuntimeException("eglGetDisplay failed " +
+ GLUtils.getEGLErrorString(mEgl.eglGetError()));
+ }
+
+ int[] version = new int[2];
+ if (!mEgl.eglInitialize(mEglDisplay, version)) {
+ throw new RuntimeException("eglInitialize failed " +
+ GLUtils.getEGLErrorString(mEgl.eglGetError()));
+ }
+
+ mEglConfig = chooseEglConfig();
+ if (mEglConfig == null) {
+ throw new RuntimeException("eglConfig not initialized");
+ }
+
+ mEglContext = createContext(mEgl, mEglDisplay, mEglConfig);
+
+ mEglSurface = mEgl.eglCreateWindowSurface(mEglDisplay, mEglConfig, surfaceHolder, null);
+
+ if (mEglSurface == null || mEglSurface == EGL_NO_SURFACE) {
+ int error = mEgl.eglGetError();
+ if (error == EGL_BAD_NATIVE_WINDOW) {
+ Log.e(GL_LOG_TAG, "createWindowSurface returned EGL_BAD_NATIVE_WINDOW.");
+ return;
+ }
+ throw new RuntimeException("createWindowSurface failed " +
+ GLUtils.getEGLErrorString(error));
+ }
+
+ if (!mEgl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)) {
+ throw new RuntimeException("eglMakeCurrent failed " +
+ GLUtils.getEGLErrorString(mEgl.eglGetError()));
+ }
+
+ mGL = mEglContext.getGL();
+ }
+
+
+ EGLContext createContext(EGL10 egl, EGLDisplay eglDisplay, EGLConfig eglConfig) {
+ int[] attrib_list = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
+ return egl.eglCreateContext(eglDisplay, eglConfig, EGL_NO_CONTEXT, attrib_list);
+ }
+
+ private EGLConfig chooseEglConfig() {
+ int[] configsCount = new int[1];
+ EGLConfig[] configs = new EGLConfig[1];
+ int[] configSpec = getConfig();
+ if (!mEgl.eglChooseConfig(mEglDisplay, configSpec, configs, 1, configsCount)) {
+ throw new IllegalArgumentException("eglChooseConfig failed " +
+ GLUtils.getEGLErrorString(mEgl.eglGetError()));
+ } else if (configsCount[0] > 0) {
+ return configs[0];
+ }
+ return null;
+ }
+
+ private int[] getConfig() {
+ return new int[] {
+ EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+ EGL_RED_SIZE, 8,
+ EGL_GREEN_SIZE, 8,
+ EGL_BLUE_SIZE, 8,
+ EGL_ALPHA_SIZE, 0,
+ EGL_DEPTH_SIZE, 0,
+ EGL_STENCIL_SIZE, 0,
+ EGL_NONE
+ };
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBar.java
index 61da1f5..37c77f6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBar.java
@@ -16,6 +16,7 @@
package com.android.systemui.statusbar;
+import android.app.ActivityManager;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
@@ -26,6 +27,7 @@
import android.os.ServiceManager;
import android.util.Slog;
import android.util.Log;
+import android.view.Display;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
@@ -117,6 +119,15 @@
| WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
| WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
PixelFormat.RGBX_8888);
+
+ // the status bar should be in an overlay if possible
+ final Display defaultDisplay
+ = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE))
+ .getDefaultDisplay();
+ if (ActivityManager.isHighEndGfx(defaultDisplay)) {
+ lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
+ }
+
lp.gravity = getStatusBarGravity();
lp.setTitle("StatusBar");
lp.packageName = mContext.getPackageName();
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 fe9eceb..dd8e3e8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -475,6 +475,10 @@
| WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
| WindowManager.LayoutParams.FLAG_SLIPPERY,
PixelFormat.OPAQUE);
+ // this will allow the navbar to run in an overlay on devices that support this
+ if (ActivityManager.isHighEndGfx(mDisplay)) {
+ lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
+ }
lp.setTitle("NavigationBar");
switch (rotation) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
index 6368d1d..840087c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
@@ -60,6 +60,7 @@
Drawable mGlowBG;
float mGlowAlpha = 0f, mGlowScale = 1f, mDrawingAlpha = 1f;
boolean mSupportsLongpress = true;
+ RectF mRect = new RectF(0f,0f,0f,0f);
Runnable mCheckLongPress = new Runnable() {
public void run() {
@@ -120,8 +121,9 @@
mGlowBG.setAlpha((int)(mGlowAlpha * 255));
mGlowBG.draw(canvas);
canvas.restore();
-
- canvas.saveLayerAlpha(null, (int)(mDrawingAlpha * 255), Canvas.ALL_SAVE_FLAG);
+ mRect.right = w;
+ mRect.bottom = h;
+ canvas.saveLayerAlpha(mRect, (int)(mDrawingAlpha * 255), Canvas.ALL_SAVE_FLAG);
}
super.onDraw(canvas);
if (mGlowBG != null) {
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 16db1d7..60dfdac 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
@@ -225,7 +225,7 @@
public void addSignalCluster(SignalCluster cluster) {
mSignalClusters.add(cluster);
cluster.setWifiIndicators(
- mWifiEnabled,
+ mWifiConnected, // only show wifi in the cluster if connected
mWifiIconId,
mWifiActivityIconId);
cluster.setMobileDataIndicators(
@@ -862,7 +862,7 @@
// NB: the mLast*s will be updated later
for (SignalCluster cluster : mSignalClusters) {
cluster.setWifiIndicators(
- mWifiEnabled,
+ mWifiConnected, // only show wifi in the cluster if connected
mWifiIconId,
mWifiActivityIconId);
cluster.setMobileDataIndicators(
diff --git a/preloaded-classes b/preloaded-classes
index 8136f8e..1b2bfd5 100644
--- a/preloaded-classes
+++ b/preloaded-classes
@@ -7,6 +7,9 @@
android.accounts.Account$1
android.accounts.AccountManager
android.accounts.AccountManager$12
+android.accounts.AccountManager$AmsTask
+android.accounts.AccountManager$AmsTask$1
+android.accounts.AccountManager$AmsTask$Response
android.accounts.AccountManagerFuture
android.accounts.IAccountManager
android.accounts.IAccountManager$Stub
@@ -15,10 +18,17 @@
android.accounts.IAccountManagerResponse$Stub
android.animation.Animator
android.animation.Animator$AnimatorListener
+android.animation.AnimatorListenerAdapter
android.animation.FloatEvaluator
+android.animation.FloatKeyframeSet
android.animation.IntEvaluator
+android.animation.Keyframe
+android.animation.Keyframe$FloatKeyframe
+android.animation.KeyframeSet
android.animation.LayoutTransition$TransitionListener
+android.animation.ObjectAnimator
android.animation.PropertyValuesHolder
+android.animation.PropertyValuesHolder$FloatPropertyValuesHolder
android.animation.TimeInterpolator
android.animation.TypeEvaluator
android.animation.ValueAnimator
@@ -27,10 +37,10 @@
android.animation.ValueAnimator$3
android.animation.ValueAnimator$4
android.animation.ValueAnimator$5
+android.animation.ValueAnimator$AnimationHandler
android.app.ActionBar
android.app.ActionBar$LayoutParams
android.app.Activity
-android.app.Activity$NonConfigurationInstances
android.app.ActivityManager
android.app.ActivityManagerNative
android.app.ActivityManagerNative$1
@@ -54,7 +64,6 @@
android.app.ActivityThread$ServiceArgsData
android.app.ActivityThread$StopInfo
android.app.AlertDialog
-android.app.AlertDialog$Builder
android.app.AppGlobals
android.app.Application
android.app.ApplicationErrorReport$CrashInfo
@@ -62,7 +71,6 @@
android.app.ApplicationPackageManager
android.app.ApplicationPackageManager$ResourceName
android.app.ApplicationThreadNative
-android.app.BackStackRecord
android.app.ContextImpl
android.app.ContextImpl$1
android.app.ContextImpl$10
@@ -87,6 +95,10 @@
android.app.ContextImpl$28
android.app.ContextImpl$29
android.app.ContextImpl$3
+android.app.ContextImpl$30
+android.app.ContextImpl$31
+android.app.ContextImpl$32
+android.app.ContextImpl$33
android.app.ContextImpl$4
android.app.ContextImpl$5
android.app.ContextImpl$6
@@ -99,12 +111,9 @@
android.app.Dialog
android.app.Dialog$1
android.app.Dialog$ListenersHandler
-android.app.Fragment
android.app.FragmentManager
-android.app.FragmentManager$BackStackEntry
android.app.FragmentManagerImpl
android.app.FragmentManagerImpl$1
-android.app.FragmentTransaction
android.app.IActivityManager
android.app.IActivityManager$ContentProviderHolder
android.app.IActivityManager$ContentProviderHolder$1
@@ -114,15 +123,29 @@
android.app.IApplicationThread
android.app.IInstrumentationWatcher
android.app.IInstrumentationWatcher$Stub
+android.app.INotificationManager
+android.app.INotificationManager$Stub
+android.app.INotificationManager$Stub$Proxy
+android.app.ISearchManager
+android.app.ISearchManager$Stub
+android.app.IServiceConnection
+android.app.IServiceConnection$Stub
android.app.Instrumentation
android.app.IntentReceiverLeaked
-android.app.ListActivity
+android.app.IntentService
+android.app.IntentService$ServiceHandler
android.app.LoadedApk
android.app.LoadedApk$ReceiverDispatcher
android.app.LoadedApk$ReceiverDispatcher$Args
android.app.LoadedApk$ReceiverDispatcher$InnerReceiver
+android.app.LoadedApk$ServiceDispatcher
+android.app.LoadedApk$ServiceDispatcher$ConnectionInfo
+android.app.LoadedApk$ServiceDispatcher$DeathMonitor
+android.app.LoadedApk$ServiceDispatcher$InnerConnection
+android.app.LoadedApk$ServiceDispatcher$RunConnection
android.app.LoadedApk$WarningContextClassLoader
android.app.NativeActivity
+android.app.NotificationManager
android.app.PendingIntent
android.app.PendingIntent$1
android.app.QueuedWork
@@ -130,6 +153,7 @@
android.app.ResultInfo
android.app.ResultInfo$1
android.app.Service
+android.app.ServiceConnectionLeaked
android.app.SharedPreferencesImpl
android.app.SharedPreferencesImpl$1
android.app.SharedPreferencesImpl$2
@@ -143,6 +167,8 @@
android.app.backup.BackupHelperDispatcher
android.app.backup.BackupHelperDispatcher$Header
android.app.backup.FileBackupHelperBase
+android.app.backup.FullBackup
+android.appwidget.AppWidgetManager
android.bluetooth.BluetoothAudioGateway
android.bluetooth.BluetoothSocket
android.bluetooth.HeadsetBase
@@ -153,6 +179,7 @@
android.content.BroadcastReceiver
android.content.BroadcastReceiver$PendingResult
android.content.ComponentCallbacks
+android.content.ComponentCallbacks2
android.content.ComponentName
android.content.ComponentName$1
android.content.ContentProvider
@@ -161,6 +188,7 @@
android.content.ContentProviderProxy
android.content.ContentResolver
android.content.ContentResolver$CursorWrapperInner
+android.content.ContentResolver$ParcelFileDescriptorInner
android.content.ContentUris
android.content.ContentValues
android.content.ContentValues$1
@@ -226,6 +254,7 @@
android.content.res.ColorStateList$1
android.content.res.CompatibilityInfo
android.content.res.CompatibilityInfo$1
+android.content.res.CompatibilityInfo$2
android.content.res.Configuration
android.content.res.Configuration$1
android.content.res.ObbInfo
@@ -235,6 +264,7 @@
android.content.res.Resources$1
android.content.res.Resources$Theme
android.content.res.StringBlock
+android.content.res.StringBlock$StyleIDs
android.content.res.TypedArray
android.content.res.XmlBlock
android.content.res.XmlBlock$Parser
@@ -252,6 +282,8 @@
android.database.ContentObserver$Transport
android.database.CrossProcessCursor
android.database.Cursor
+android.database.CursorToBulkCursorAdaptor
+android.database.CursorToBulkCursorAdaptor$ContentObserverProxy
android.database.CursorWindow
android.database.CursorWindow$1
android.database.CursorWrapper
@@ -263,6 +295,8 @@
android.database.IBulkCursor
android.database.IContentObserver
android.database.IContentObserver$Stub
+android.database.IContentObserver$Stub$Proxy
+android.database.MatrixCursor
android.database.Observable
android.database.sqlite.DatabaseObjectNotClosedException
android.database.sqlite.SQLiteClosable
@@ -272,8 +306,8 @@
android.database.sqlite.SQLiteDatabase
android.database.sqlite.SQLiteDatabase$1
android.database.sqlite.SQLiteDatabase$CustomFunction
+android.database.sqlite.SQLiteDatabase$DatabaseReentrantLock
android.database.sqlite.SQLiteDebug
-android.database.sqlite.SQLiteDebug$DbStats
android.database.sqlite.SQLiteDebug$PagerStats
android.database.sqlite.SQLiteDirectCursorDriver
android.database.sqlite.SQLiteOpenHelper
@@ -290,6 +324,7 @@
android.ddm.DdmHandleThread
android.ddm.DdmRegister
android.debug.JNITest
+android.drm.DrmManagerClient
android.emoji.EmojiFactory
android.graphics.AvoidXfermode
android.graphics.Bitmap
@@ -342,7 +377,9 @@
android.graphics.PixelFormat
android.graphics.PixelXorXfermode
android.graphics.Point
+android.graphics.Point$1
android.graphics.PointF
+android.graphics.PointF$1
android.graphics.PorterDuff$Mode
android.graphics.PorterDuffColorFilter
android.graphics.PorterDuffXfermode
@@ -362,6 +399,7 @@
android.graphics.SurfaceTexture
android.graphics.SweepGradient
android.graphics.TableMaskFilter
+android.graphics.TemporaryBuffer
android.graphics.Typeface
android.graphics.Xfermode
android.graphics.YuvImage
@@ -378,6 +416,7 @@
android.graphics.drawable.ColorDrawable$ColorState
android.graphics.drawable.Drawable
android.graphics.drawable.Drawable$Callback
+android.graphics.drawable.Drawable$Callback2
android.graphics.drawable.Drawable$ConstantState
android.graphics.drawable.DrawableContainer
android.graphics.drawable.DrawableContainer$1
@@ -392,13 +431,25 @@
android.graphics.drawable.NinePatchDrawable$NinePatchState
android.graphics.drawable.RotateDrawable
android.graphics.drawable.RotateDrawable$RotateState
+android.graphics.drawable.ScaleDrawable
+android.graphics.drawable.ScaleDrawable$ScaleState
+android.graphics.drawable.ShapeDrawable
+android.graphics.drawable.ShapeDrawable$ShapeState
android.graphics.drawable.StateListDrawable
android.graphics.drawable.StateListDrawable$StateListState
android.graphics.drawable.TransitionDrawable
android.graphics.drawable.TransitionDrawable$TransitionState
+android.graphics.drawable.shapes.RectShape
+android.graphics.drawable.shapes.RoundRectShape
+android.graphics.drawable.shapes.Shape
android.hardware.Camera
android.hardware.Camera$CameraInfo
+android.hardware.Camera$Face
+android.hardware.Camera$Parameters
android.hardware.SensorManager
+android.hardware.usb.UsbDevice
+android.hardware.usb.UsbDeviceConnection
+android.hardware.usb.UsbRequest
android.inputmethodservice.ExtractEditText
android.location.GpsSatellite
android.location.GpsStatus
@@ -407,26 +458,40 @@
android.location.ILocationManager$Stub
android.location.ILocationManager$Stub$Proxy
android.location.Location
+android.location.Location$1
+android.location.LocationListener
android.location.LocationManager
android.media.AudioFormat
android.media.AudioManager
android.media.AudioManager$1
+android.media.AudioManager$2
android.media.AudioManager$FocusEventHandlerDelegate
android.media.AudioManager$FocusEventHandlerDelegate$1
android.media.AudioRecord
android.media.AudioSystem
android.media.AudioTrack
-android.media.CamcorderProfile
+android.media.CameraProfile
android.media.DecoderCapabilities
android.media.IAudioFocusDispatcher
android.media.IAudioFocusDispatcher$Stub
+android.media.IAudioService
+android.media.IAudioService$Stub
+android.media.IAudioService$Stub$Proxy
+android.media.IRemoteControlClientDispatcher
+android.media.IRemoteControlClientDispatcher$Stub
android.media.JetPlayer
+android.media.MediaFile
android.media.MediaPlayer
+android.media.MediaPlayer$OnBufferingUpdateListener
+android.media.MediaPlayer$OnCompletionListener
+android.media.MediaPlayer$OnErrorListener
+android.media.MediaPlayer$OnInfoListener
+android.media.MediaPlayer$OnPreparedListener
+android.media.MediaScanner
android.media.ToneGenerator
android.net.ConnectivityManager
android.net.Credentials
-android.net.DhcpInfo
-android.net.DhcpInfo$1
+android.net.DhcpInfoInternal
android.net.IConnectivityManager
android.net.IConnectivityManager$Stub
android.net.IConnectivityManager$Stub$Proxy
@@ -441,8 +506,9 @@
android.net.NetworkInfo$State
android.net.NetworkUtils
android.net.Proxy
-android.net.ProxyProperties
-android.net.ProxyProperties$1
+android.net.SSLCertificateSocketFactory
+android.net.SSLCertificateSocketFactory$1
+android.net.SSLSessionCache
android.net.TrafficStats
android.net.Uri
android.net.Uri$1
@@ -450,12 +516,18 @@
android.net.Uri$AbstractPart
android.net.Uri$Builder
android.net.Uri$HierarchicalUri
+android.net.Uri$OpaqueUri
android.net.Uri$Part
android.net.Uri$Part$EmptyPart
android.net.Uri$PathPart
android.net.Uri$PathSegments
android.net.Uri$PathSegmentsBuilder
android.net.Uri$StringUri
+android.net.WebAddress
+android.net.http.AndroidHttpClient
+android.net.http.AndroidHttpClient$1
+android.net.http.AndroidHttpClient$2
+android.net.http.AndroidHttpClient$CurlLogger
android.net.wifi.WifiNative
android.nfc.NdefMessage
android.nfc.NdefRecord
@@ -477,6 +549,7 @@
android.os.AsyncTask$SerialExecutor$1
android.os.AsyncTask$Status
android.os.AsyncTask$WorkerRunnable
+android.os.BatteryStats
android.os.Binder
android.os.BinderProxy
android.os.Build
@@ -510,6 +583,7 @@
android.os.ParcelFileDescriptor
android.os.ParcelFileDescriptor$1
android.os.Parcelable
+android.os.Parcelable$ClassLoaderCreator
android.os.Parcelable$Creator
android.os.PatternMatcher
android.os.PatternMatcher$1
@@ -535,6 +609,7 @@
android.os.StrictMode$AndroidBlockGuardPolicy$1
android.os.StrictMode$AndroidCloseGuardReporter
android.os.StrictMode$InstanceCountViolation
+android.os.StrictMode$InstanceTracker
android.os.StrictMode$LogStackTrace
android.os.StrictMode$Span
android.os.StrictMode$StrictModeDiskReadViolation
@@ -548,7 +623,11 @@
android.os.SystemClock
android.os.SystemProperties
android.os.UEventObserver
-android.pim.EventRecurrence
+android.os.Vibrator
+android.os.storage.IMountService
+android.os.storage.IMountService$Stub
+android.os.storage.IMountService$Stub$Proxy
+android.preference.PreferenceActivity
android.preference.PreferenceManager
android.provider.BaseColumns
android.provider.Settings$NameValueCache
@@ -559,6 +638,7 @@
android.server.BluetoothA2dpService
android.server.BluetoothEventLoop
android.server.BluetoothService
+android.telephony.PhoneNumberUtils
android.telephony.TelephonyManager
android.text.AndroidBidi
android.text.AndroidCharacter
@@ -585,6 +665,7 @@
android.text.ParcelableSpan
android.text.Selection
android.text.Selection$END
+android.text.Selection$PositionIterator
android.text.Selection$START
android.text.SpanWatcher
android.text.Spannable
@@ -595,6 +676,16 @@
android.text.Spanned
android.text.SpannedString
android.text.StaticLayout
+android.text.TextDirectionHeuristic
+android.text.TextDirectionHeuristics
+android.text.TextDirectionHeuristics$1
+android.text.TextDirectionHeuristics$AnyStrong
+android.text.TextDirectionHeuristics$CharCount
+android.text.TextDirectionHeuristics$FirstStrong
+android.text.TextDirectionHeuristics$TextDirectionAlgorithm
+android.text.TextDirectionHeuristics$TextDirectionHeuristicImpl
+android.text.TextDirectionHeuristics$TextDirectionHeuristicInternal
+android.text.TextDirectionHeuristics$TriState
android.text.TextLine
android.text.TextPaint
android.text.TextUtils
@@ -603,12 +694,14 @@
android.text.TextUtils$TruncateAt
android.text.TextWatcher
android.text.format.Time
+android.text.method.AllCapsTransformationMethod
android.text.method.ArrowKeyMovementMethod
android.text.method.BaseKeyListener
android.text.method.BaseMovementMethod
android.text.method.KeyListener
android.text.method.MetaKeyKeyListener
android.text.method.MovementMethod
+android.text.method.QwertyKeyListener
android.text.method.ReplacementTransformationMethod
android.text.method.ReplacementTransformationMethod$ReplacementCharSequence
android.text.method.ReplacementTransformationMethod$SpannedReplacementCharSequence
@@ -616,6 +709,9 @@
android.text.method.TextKeyListener
android.text.method.TextKeyListener$Capitalize
android.text.method.TransformationMethod
+android.text.method.TransformationMethod2
+android.text.method.WordIterator
+android.text.method.WordIterator$1
android.text.style.AlignmentSpan
android.text.style.CharacterStyle
android.text.style.LeadingMarginSpan
@@ -624,29 +720,35 @@
android.text.style.MetricAffectingSpan
android.text.style.ParagraphStyle
android.text.style.ReplacementSpan
+android.text.style.StyleSpan
+android.text.style.SuggestionSpan
android.text.style.UpdateAppearance
android.text.style.UpdateLayout
android.text.style.WrapTogetherSpan
android.util.AndroidException
android.util.AndroidRuntimeException
android.util.AttributeSet
-android.util.DebugUtils
android.util.DisplayMetrics
android.util.EventLog
android.util.EventLog$Event
android.util.FinitePool
android.util.FloatMath
+android.util.FloatProperty
+android.util.LocaleUtil
android.util.Log
android.util.Log$1
android.util.Log$TerribleFailureHandler
android.util.LongSparseArray
+android.util.LruCache
android.util.Pair
android.util.Patterns
android.util.Pool
android.util.Poolable
android.util.PoolableManager
android.util.Pools
+android.util.Property
android.util.Singleton
+android.util.Slog
android.util.SparseArray
android.util.SparseBooleanArray
android.util.SparseIntArray
@@ -659,24 +761,36 @@
android.view.AbsSavedState$2
android.view.ActionMode
android.view.ActionMode$Callback
+android.view.CompatibilityInfoHolder
android.view.ContextMenu
android.view.ContextMenu$ContextMenuInfo
android.view.ContextThemeWrapper
android.view.Display
+android.view.DisplayList
android.view.FallbackEventHandler
android.view.FocusFinder
android.view.FocusFinder$1
android.view.FocusFinder$SequentialFocusComparator
android.view.GLES20Canvas
android.view.GLES20Canvas$CanvasFinalizer
+android.view.GLES20DisplayList
+android.view.GLES20DisplayList$DisplayListFinalizer
+android.view.GLES20Layer
+android.view.GLES20Layer$Finalizer
+android.view.GLES20RecordingCanvas
+android.view.GLES20RecordingCanvas$1
+android.view.GLES20RenderLayer
+android.view.GestureDetector$OnDoubleTapListener
+android.view.GestureDetector$OnGestureListener
android.view.Gravity
android.view.HardwareCanvas
+android.view.HardwareLayer
android.view.HardwareRenderer
android.view.HardwareRenderer$Gl20Renderer
android.view.HardwareRenderer$GlRenderer
-android.view.HardwareRenderer$GlRenderer$ComponentSizeChooser
-android.view.HardwareRenderer$GlRenderer$EglConfigChooser
android.view.HardwareRenderer$HardwareDrawCallbacks
+android.view.IRotationWatcher
+android.view.IRotationWatcher$Stub
android.view.IWindow
android.view.IWindow$Stub
android.view.IWindowManager
@@ -689,6 +803,8 @@
android.view.InputChannel$1
android.view.InputEvent
android.view.InputEvent$1
+android.view.InputEventConsistencyVerifier
+android.view.InputEventConsistencyVerifier$KeyState
android.view.InputHandler
android.view.InputQueue
android.view.InputQueue$Callback
@@ -702,12 +818,17 @@
android.view.LayoutInflater
android.view.LayoutInflater$Factory
android.view.LayoutInflater$Factory2
+android.view.LayoutInflater$Filter
android.view.Menu
android.view.MenuInflater
android.view.MenuInflater$MenuState
android.view.MenuItem
android.view.MotionEvent
android.view.MotionEvent$1
+android.view.MotionEvent$PointerCoords
+android.view.MotionEvent$PointerProperties
+android.view.PointerIcon
+android.view.PointerIcon$1
android.view.Surface
android.view.Surface$1
android.view.Surface$CompatibleCanvas
@@ -719,10 +840,22 @@
android.view.SurfaceView$1
android.view.SurfaceView$2
android.view.SurfaceView$3
+android.view.SurfaceView$4
+android.view.SurfaceView$MyWindow
+android.view.TextureView
android.view.VelocityTracker
android.view.VelocityTracker$1
-android.view.VelocityTracker$Pointer
android.view.View
+android.view.View$10
+android.view.View$11
+android.view.View$12
+android.view.View$13
+android.view.View$4
+android.view.View$5
+android.view.View$6
+android.view.View$7
+android.view.View$8
+android.view.View$9
android.view.View$AttachInfo
android.view.View$AttachInfo$Callbacks
android.view.View$BaseSavedState
@@ -733,29 +866,31 @@
android.view.View$OnCreateContextMenuListener
android.view.View$OnFocusChangeListener
android.view.View$OnKeyListener
+android.view.View$OnLayoutChangeListener
android.view.View$OnLongClickListener
android.view.View$OnTouchListener
android.view.View$PerformClick
android.view.View$ScrollabilityCache
android.view.View$UnsetPressedState
android.view.ViewConfiguration
-android.view.ViewDebug
android.view.ViewGroup
android.view.ViewGroup$3
android.view.ViewGroup$LayoutParams
android.view.ViewGroup$MarginLayoutParams
+android.view.ViewGroup$OnHierarchyChangeListener
android.view.ViewGroup$TouchTarget
android.view.ViewManager
android.view.ViewParent
-android.view.ViewRoot
-android.view.ViewRoot$1
-android.view.ViewRoot$2
-android.view.ViewRoot$InputMethodCallback
-android.view.ViewRoot$ResizedInfo
-android.view.ViewRoot$RunQueue
-android.view.ViewRoot$RunQueue$HandlerAction
-android.view.ViewRoot$TrackballAxis
-android.view.ViewRoot$W
+android.view.ViewRootImpl
+android.view.ViewRootImpl$2
+android.view.ViewRootImpl$3
+android.view.ViewRootImpl$AccessibilityInteractionConnectionManager
+android.view.ViewRootImpl$InputMethodCallback
+android.view.ViewRootImpl$ResizedInfo
+android.view.ViewRootImpl$RunQueue
+android.view.ViewRootImpl$RunQueue$HandlerAction
+android.view.ViewRootImpl$TrackballAxis
+android.view.ViewRootImpl$W
android.view.ViewStub
android.view.ViewTreeObserver
android.view.ViewTreeObserver$InternalInsetsInfo
@@ -771,17 +906,21 @@
android.view.WindowManager$LayoutParams
android.view.WindowManager$LayoutParams$1
android.view.WindowManagerImpl
+android.view.WindowManagerImpl$CompatModeWrapper
android.view.accessibility.AccessibilityEvent
android.view.accessibility.AccessibilityEventSource
android.view.accessibility.AccessibilityManager
android.view.accessibility.AccessibilityManager$1
+android.view.accessibility.AccessibilityManager$AccessibilityStateChangeListener
android.view.accessibility.AccessibilityManager$MyHandler
+android.view.accessibility.AccessibilityRecord
android.view.accessibility.IAccessibilityManager
android.view.accessibility.IAccessibilityManager$Stub
android.view.accessibility.IAccessibilityManager$Stub$Proxy
android.view.accessibility.IAccessibilityManagerClient
android.view.accessibility.IAccessibilityManagerClient$Stub
android.view.animation.AccelerateDecelerateInterpolator
+android.view.animation.AccelerateInterpolator
android.view.animation.AlphaAnimation
android.view.animation.Animation
android.view.animation.AnimationUtils
@@ -794,27 +933,30 @@
android.view.inputmethod.EditorInfo
android.view.inputmethod.EditorInfo$1
android.view.inputmethod.ExtractedText
-android.view.inputmethod.ExtractedTextRequest
-android.view.inputmethod.ExtractedTextRequest$1
+android.view.inputmethod.ExtractedText$1
android.view.inputmethod.InputConnection
android.view.inputmethod.InputMethodManager
android.view.inputmethod.InputMethodManager$1
android.view.inputmethod.InputMethodManager$ControlledInputConnectionWrapper
android.view.inputmethod.InputMethodManager$H
-android.webkit.LoadListener
+android.webkit.JniUtil
android.webkit.PluginManager
+android.webkit.WebTextView
android.webkit.WebView
-android.webkit.WebView$HitTestResult
android.webkit.WebViewCore
-android.webkit.WebViewCore$TouchUpData
android.widget.AbsListView
+android.widget.AbsListView$1
android.widget.AbsListView$2
android.widget.AbsListView$AdapterDataSetObserver
+android.widget.AbsListView$CheckForTap
android.widget.AbsListView$LayoutParams
android.widget.AbsListView$OnScrollListener
+android.widget.AbsListView$PerformClick
android.widget.AbsListView$RecycleBin
android.widget.AbsListView$SavedState
android.widget.AbsListView$SavedState$1
+android.widget.AbsListView$SelectionBoundsAdjuster
+android.widget.AbsListView$WindowRunnnable
android.widget.AbsSpinner
android.widget.AbsSpinner$RecycleBin
android.widget.Adapter
@@ -825,21 +967,30 @@
android.widget.AdapterViewAnimator
android.widget.ArrayAdapter
android.widget.AutoCompleteTextView
+android.widget.AutoCompleteTextView$DropDownItemClickListener
+android.widget.AutoCompleteTextView$MyWatcher
+android.widget.AutoCompleteTextView$PassThroughClickListener
android.widget.BaseAdapter
android.widget.Button
android.widget.CheckBox
android.widget.Checkable
+android.widget.CheckedTextView
android.widget.CompoundButton
+android.widget.CursorAdapter
+android.widget.CursorFilter$CursorFilterClient
android.widget.EdgeGlow
android.widget.EditText
android.widget.ExpandableListView
android.widget.Filter
android.widget.Filter$FilterListener
+android.widget.Filter$ResultsHandler
android.widget.Filterable
android.widget.FrameLayout
android.widget.FrameLayout$LayoutParams
android.widget.Gallery
+android.widget.GridLayout
android.widget.GridView
+android.widget.HorizontalScrollView
android.widget.ImageButton
android.widget.ImageView
android.widget.ImageView$ScaleType
@@ -848,62 +999,81 @@
android.widget.ListAdapter
android.widget.ListPopupWindow
android.widget.ListPopupWindow$ListSelectorHider
+android.widget.ListPopupWindow$PopupDataSetObserver
android.widget.ListPopupWindow$PopupScrollListener
android.widget.ListPopupWindow$PopupTouchInterceptor
android.widget.ListPopupWindow$ResizePopupRunnable
android.widget.ListView
android.widget.ListView$ArrowScrollFocusResult
+android.widget.NumberPicker
android.widget.OverScroller
android.widget.OverScroller$SplineOverScroller
android.widget.PopupWindow
android.widget.PopupWindow$1
android.widget.ProgressBar
+android.widget.ProgressBar$SavedState
+android.widget.ProgressBar$SavedState$1
android.widget.RelativeLayout
android.widget.RelativeLayout$DependencyGraph
android.widget.RelativeLayout$DependencyGraph$Node
android.widget.RelativeLayout$DependencyGraph$Node$1
android.widget.RelativeLayout$LayoutParams
+android.widget.RemoteViews
+android.widget.RemoteViews$1
+android.widget.RemoteViews$Action
+android.widget.RemoteViews$MemoryUsageCounter
+android.widget.RemoteViews$ReflectionAction
android.widget.RemoteViewsAdapter$RemoteAdapterConnectionCallback
android.widget.ScrollBarDrawable
android.widget.ScrollView
android.widget.Scroller
+android.widget.SearchView
+android.widget.Spinner
android.widget.SpinnerAdapter
-android.widget.Switch
+android.widget.StackView
+android.widget.TabHost
android.widget.TabWidget
android.widget.TableLayout
android.widget.TableRow
android.widget.TextView
android.widget.TextView$3
+android.widget.TextView$Blink
android.widget.TextView$BufferType
android.widget.TextView$ChangeWatcher
android.widget.TextView$CharWrapper
android.widget.TextView$Drawables
android.widget.TextView$InputContentType
+android.widget.TextView$InputMethodState
android.widget.TextView$OnEditorActionListener
android.widget.TextView$SavedState
-android.widget.TextView$SavedState$1
+android.widget.TextView$TextAlign
+android.widget.VideoView
+android.widget.ViewAnimator
+com.android.i18n.phonenumbers.AsYouTypeFormatter
+com.android.i18n.phonenumbers.PhoneNumberUtil
com.android.internal.R$styleable
com.android.internal.app.ActionBarImpl
com.android.internal.app.ActionBarImpl$1
com.android.internal.app.ActionBarImpl$2
-com.android.internal.app.ActionBarImpl$3
-com.android.internal.app.ActionBarImpl$4
com.android.internal.app.AlertController
com.android.internal.app.AlertController$1
com.android.internal.app.AlertController$ButtonHandler
com.android.internal.appwidget.IAppWidgetService
com.android.internal.appwidget.IAppWidgetService$Stub
-com.android.internal.graphics.NativeUtils
+com.android.internal.appwidget.IAppWidgetService$Stub$Proxy
+com.android.internal.content.NativeLibraryHelper
com.android.internal.logging.AndroidConfig
com.android.internal.logging.AndroidHandler
com.android.internal.logging.AndroidHandler$1
com.android.internal.os.AndroidPrintStream
+com.android.internal.os.BatteryStatsImpl
com.android.internal.os.BinderInternal
com.android.internal.os.BinderInternal$GcWatcher
com.android.internal.os.LoggingPrintStream
com.android.internal.os.LoggingPrintStream$1
com.android.internal.os.RuntimeInit
com.android.internal.os.RuntimeInit$1
+com.android.internal.os.RuntimeInit$Arguments
com.android.internal.os.RuntimeInit$UncaughtHandler
com.android.internal.os.SamplingProfilerIntegration
com.android.internal.os.ZygoteConnection
@@ -916,19 +1086,24 @@
com.android.internal.policy.impl.PhoneLayoutInflater
com.android.internal.policy.impl.PhoneWindow
com.android.internal.policy.impl.PhoneWindow$1
-com.android.internal.policy.impl.PhoneWindow$2
+com.android.internal.policy.impl.PhoneWindow$ActionMenuPresenterCallback
com.android.internal.policy.impl.PhoneWindow$DecorView
com.android.internal.policy.impl.PhoneWindow$DialogMenuCallback
com.android.internal.policy.impl.PhoneWindow$PanelFeatureState
com.android.internal.policy.impl.PhoneWindow$PanelFeatureState$SavedState
com.android.internal.policy.impl.PhoneWindow$PanelFeatureState$SavedState$1
+com.android.internal.policy.impl.PhoneWindow$RotationWatcher
+com.android.internal.policy.impl.PhoneWindow$RotationWatcher$1
com.android.internal.policy.impl.Policy
+com.android.internal.telephony.ITelephony
+com.android.internal.telephony.ITelephony$Stub
com.android.internal.telephony.ITelephonyRegistry
com.android.internal.telephony.ITelephonyRegistry$Stub
com.android.internal.telephony.ITelephonyRegistry$Stub$Proxy
com.android.internal.telephony.Phone$State
com.android.internal.util.ArrayUtils
com.android.internal.util.FastXmlSerializer
+com.android.internal.util.Preconditions
com.android.internal.util.XmlUtils
com.android.internal.view.BaseIWindow
com.android.internal.view.IInputConnectionWrapper
@@ -951,21 +1126,136 @@
com.android.internal.view.InputBindResult$1
com.android.internal.view.RootViewSurfaceTaker
com.android.internal.view.menu.ActionMenuItem
+com.android.internal.view.menu.ActionMenuItemView
+com.android.internal.view.menu.ActionMenuPresenter
+com.android.internal.view.menu.ActionMenuPresenter$OverflowMenuButton
+com.android.internal.view.menu.ActionMenuPresenter$PopupPresenterCallback
com.android.internal.view.menu.ActionMenuView
-com.android.internal.view.menu.ActionMenuView$1
-com.android.internal.view.menu.ActionMenuView$OverflowMenuButton
+com.android.internal.view.menu.ActionMenuView$ActionMenuChildView
+com.android.internal.view.menu.ActionMenuView$LayoutParams
+com.android.internal.view.menu.BaseMenuPresenter
com.android.internal.view.menu.MenuBuilder
com.android.internal.view.menu.MenuBuilder$Callback
com.android.internal.view.menu.MenuBuilder$ItemInvoker
-com.android.internal.view.menu.MenuBuilder$MenuType
com.android.internal.view.menu.MenuItemImpl
+com.android.internal.view.menu.MenuPresenter
+com.android.internal.view.menu.MenuPresenter$Callback
com.android.internal.view.menu.MenuView
+com.android.internal.view.menu.MenuView$ItemView
+com.android.internal.widget.AbsActionBarView
+com.android.internal.widget.AbsActionBarView$VisibilityAnimListener
com.android.internal.widget.ActionBarContainer
com.android.internal.widget.ActionBarContextView
com.android.internal.widget.ActionBarView
com.android.internal.widget.ActionBarView$1
com.android.internal.widget.ActionBarView$2
+com.android.internal.widget.ActionBarView$3
+com.android.internal.widget.ActionBarView$ExpandedActionViewMenuPresenter
+com.android.internal.widget.ActionBarView$HomeView
+com.android.internal.widget.ActionBarView$SavedState
+com.android.internal.widget.ActionBarView$SavedState$1
com.android.internal.widget.DialogTitle
+com.android.internal.widget.EditableInputConnection
+com.android.internal.widget.ScrollingTabContainerView
+com.android.org.bouncycastle.asn1.ASN1Choice
+com.android.org.bouncycastle.asn1.ASN1Encodable
+com.android.org.bouncycastle.asn1.ASN1EncodableVector
+com.android.org.bouncycastle.asn1.ASN1InputStream
+com.android.org.bouncycastle.asn1.ASN1Integer
+com.android.org.bouncycastle.asn1.ASN1Null
+com.android.org.bouncycastle.asn1.ASN1Object
+com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier
+com.android.org.bouncycastle.asn1.ASN1OctetString
+com.android.org.bouncycastle.asn1.ASN1OctetStringParser
+com.android.org.bouncycastle.asn1.ASN1Sequence
+com.android.org.bouncycastle.asn1.ASN1Set
+com.android.org.bouncycastle.asn1.ASN1StreamParser
+com.android.org.bouncycastle.asn1.ASN1String
+com.android.org.bouncycastle.asn1.ASN1TaggedObject
+com.android.org.bouncycastle.asn1.ASN1TaggedObjectParser
+com.android.org.bouncycastle.asn1.DERBitString
+com.android.org.bouncycastle.asn1.DERBoolean
+com.android.org.bouncycastle.asn1.DEREncodable
+com.android.org.bouncycastle.asn1.DEREncodableVector
+com.android.org.bouncycastle.asn1.DERFactory
+com.android.org.bouncycastle.asn1.DERIA5String
+com.android.org.bouncycastle.asn1.DERInteger
+com.android.org.bouncycastle.asn1.DERNull
+com.android.org.bouncycastle.asn1.DERObject
+com.android.org.bouncycastle.asn1.DERObjectIdentifier
+com.android.org.bouncycastle.asn1.DEROctetString
+com.android.org.bouncycastle.asn1.DEROutputStream
+com.android.org.bouncycastle.asn1.DERPrintableString
+com.android.org.bouncycastle.asn1.DERSequence
+com.android.org.bouncycastle.asn1.DERSet
+com.android.org.bouncycastle.asn1.DERString
+com.android.org.bouncycastle.asn1.DERT61String
+com.android.org.bouncycastle.asn1.DERTaggedObject
+com.android.org.bouncycastle.asn1.DERTags
+com.android.org.bouncycastle.asn1.DERUniversalString
+com.android.org.bouncycastle.asn1.DefiniteLengthInputStream
+com.android.org.bouncycastle.asn1.InMemoryRepresentable
+com.android.org.bouncycastle.asn1.IndefiniteLengthInputStream
+com.android.org.bouncycastle.asn1.LimitedInputStream
+com.android.org.bouncycastle.asn1.OIDTokenizer
+com.android.org.bouncycastle.asn1.bc.BCObjectIdentifiers
+com.android.org.bouncycastle.asn1.iana.IANAObjectIdentifiers
+com.android.org.bouncycastle.asn1.nist.NISTObjectIdentifiers
+com.android.org.bouncycastle.asn1.oiw.OIWObjectIdentifiers
+com.android.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers
+com.android.org.bouncycastle.asn1.x509.AlgorithmIdentifier
+com.android.org.bouncycastle.asn1.x509.BasicConstraints
+com.android.org.bouncycastle.asn1.x509.DigestInfo
+com.android.org.bouncycastle.asn1.x509.GeneralName
+com.android.org.bouncycastle.asn1.x509.GeneralNames
+com.android.org.bouncycastle.asn1.x509.RSAPublicKeyStructure
+com.android.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo
+com.android.org.bouncycastle.asn1.x509.X509Extensions
+com.android.org.bouncycastle.asn1.x509.X509Name
+com.android.org.bouncycastle.asn1.x509.X509ObjectIdentifiers
+com.android.org.bouncycastle.asn1.x9.X9ObjectIdentifiers
+com.android.org.bouncycastle.crypto.AsymmetricBlockCipher
+com.android.org.bouncycastle.crypto.CipherParameters
+com.android.org.bouncycastle.crypto.Digest
+com.android.org.bouncycastle.crypto.ExtendedDigest
+com.android.org.bouncycastle.crypto.digests.GeneralDigest
+com.android.org.bouncycastle.crypto.digests.SHA1Digest
+com.android.org.bouncycastle.crypto.encodings.PKCS1Encoding
+com.android.org.bouncycastle.crypto.encodings.PKCS1Encoding$1
+com.android.org.bouncycastle.crypto.engines.RSABlindedEngine
+com.android.org.bouncycastle.crypto.engines.RSACoreEngine
+com.android.org.bouncycastle.crypto.params.AsymmetricKeyParameter
+com.android.org.bouncycastle.crypto.params.ParametersWithRandom
+com.android.org.bouncycastle.crypto.params.RSAKeyParameters
+com.android.org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters
+com.android.org.bouncycastle.crypto.util.Pack
+com.android.org.bouncycastle.jce.interfaces.BCKeyStore
+com.android.org.bouncycastle.jce.interfaces.ConfigurableProvider
+com.android.org.bouncycastle.jce.provider.BouncyCastleProvider
+com.android.org.bouncycastle.jce.provider.BouncyCastleProvider$1
+com.android.org.bouncycastle.jce.provider.CertPathValidatorUtilities
+com.android.org.bouncycastle.jce.provider.JCERSAPublicKey
+com.android.org.bouncycastle.jce.provider.JDKDigestSignature
+com.android.org.bouncycastle.jce.provider.JDKDigestSignature$SHA1WithRSAEncryption
+com.android.org.bouncycastle.jce.provider.JDKKeyFactory
+com.android.org.bouncycastle.jce.provider.JDKKeyFactory$RSA
+com.android.org.bouncycastle.jce.provider.JDKKeyStore
+com.android.org.bouncycastle.jce.provider.PKIXCRLUtil
+com.android.org.bouncycastle.jce.provider.PKIXCertPathValidatorSpi
+com.android.org.bouncycastle.jce.provider.PKIXNameConstraintValidator
+com.android.org.bouncycastle.jce.provider.PKIXPolicyNode
+com.android.org.bouncycastle.jce.provider.RFC3280CertPathUtilities
+com.android.org.bouncycastle.jce.provider.RSAUtil
+com.android.org.bouncycastle.jce.provider.asymmetric.EC$Mappings
+com.android.org.bouncycastle.jce.provider.symmetric.AES$Mappings
+com.android.org.bouncycastle.jce.provider.symmetric.ARC4$Mappings
+com.android.org.bouncycastle.jce.provider.symmetric.Blowfish$Mappings
+com.android.org.bouncycastle.jce.provider.symmetric.DESede$Mappings
+com.android.org.bouncycastle.util.io.Streams
+com.android.org.bouncycastle.x509.ExtendedPKIXParameters
+com.android.server.NetworkManagementSocketTagger
+com.android.server.NetworkManagementSocketTagger$1
+com.android.server.NetworkManagementSocketTagger$SocketTags
com.android.server.Watchdog
com.google.android.collect.Lists
com.google.android.collect.Maps
@@ -975,23 +1265,25 @@
com.google.android.gles_jni.EGLImpl
com.google.android.gles_jni.EGLSurfaceImpl
com.google.android.gles_jni.GLImpl
-com.android.i18n.phonenumbers.PhoneNumberUtil
+dalvik.system.BaseDexClassLoader
dalvik.system.BlockGuard
dalvik.system.BlockGuard$1
dalvik.system.BlockGuard$2
dalvik.system.BlockGuard$BlockGuardPolicyException
dalvik.system.BlockGuard$Policy
-dalvik.system.BlockGuard$WrappedFileSystem
-dalvik.system.BlockGuard$WrappedNetworkSystem
dalvik.system.CloseGuard
dalvik.system.CloseGuard$DefaultReporter
dalvik.system.CloseGuard$Reporter
dalvik.system.DalvikLogHandler
dalvik.system.DalvikLogging
dalvik.system.DexFile
+dalvik.system.DexPathList
+dalvik.system.DexPathList$Element
dalvik.system.NativeStart
dalvik.system.PathClassLoader
-dalvik.system.TouchDex
+dalvik.system.SocketTagger
+dalvik.system.SocketTagger$1
+dalvik.system.StaleDexCacheError
dalvik.system.VMDebug
dalvik.system.VMRuntime
dalvik.system.VMStack
@@ -1019,58 +1311,78 @@
java.io.IOException
java.io.InputStream
java.io.InputStreamReader
-java.io.InterruptedIOException
java.io.ObjectStreamClass
java.io.ObjectStreamField
java.io.OutputStream
java.io.OutputStreamWriter
java.io.PrintStream
java.io.PrintWriter
-java.io.PushbackInputStream
java.io.RandomAccessFile
java.io.Reader
java.io.Serializable
java.io.StringWriter
java.io.Writer
+java.lang.AbstractMethodError
java.lang.AbstractStringBuilder
java.lang.Appendable
+java.lang.ArithmeticException
java.lang.ArrayIndexOutOfBoundsException
+java.lang.ArrayStoreException
+java.lang.AutoCloseable
java.lang.Boolean
java.lang.BootClassLoader
java.lang.Byte
java.lang.CaseMapper
java.lang.CharSequence
java.lang.Character
+java.lang.Character$UnicodeBlock
java.lang.Class
-java.lang.ClassCache
-java.lang.ClassCache$EnumComparator
java.lang.ClassCastException
+java.lang.ClassCircularityError
+java.lang.ClassFormatError
java.lang.ClassLoader
java.lang.ClassLoader$SystemClassLoader
java.lang.ClassNotFoundException
java.lang.Cloneable
java.lang.Comparable
+java.lang.Daemons
+java.lang.Daemons$Daemon
+java.lang.Daemons$FinalizerDaemon
+java.lang.Daemons$FinalizerWatchdogDaemon
+java.lang.Daemons$ReferenceQueueDaemon
java.lang.Double
java.lang.Enum
+java.lang.Enum$1
java.lang.Error
java.lang.Exception
java.lang.ExceptionInInitializerError
java.lang.Float
+java.lang.IllegalAccessError
+java.lang.IllegalAccessException
java.lang.IllegalArgumentException
+java.lang.IllegalMonitorStateException
java.lang.IllegalStateException
+java.lang.IllegalThreadStateException
+java.lang.IncompatibleClassChangeError
java.lang.IndexOutOfBoundsException
+java.lang.InstantiationError
+java.lang.InstantiationException
java.lang.Integer
java.lang.IntegralToString
java.lang.IntegralToString$1
java.lang.InternalError
java.lang.InterruptedException
java.lang.Iterable
-java.lang.LangAccessImpl
java.lang.LinkageError
java.lang.Long
java.lang.Math
+java.lang.NegativeArraySizeException
java.lang.NoClassDefFoundError
+java.lang.NoSuchFieldError
+java.lang.NoSuchFieldException
+java.lang.NoSuchMethodError
java.lang.NoSuchMethodException
+java.lang.NullPointerException
java.lang.Number
java.lang.NumberFormatException
java.lang.Object
@@ -1082,7 +1394,6 @@
java.lang.Runtime
java.lang.RuntimeException
java.lang.RuntimePermission
-java.lang.SecurityException
java.lang.Short
java.lang.StackOverflowError
java.lang.StackTraceElement
@@ -1091,8 +1402,10 @@
java.lang.String$CaseInsensitiveComparator
java.lang.StringBuffer
java.lang.StringBuilder
+java.lang.StringIndexOutOfBoundsException
+java.lang.StringToReal
+java.lang.StringToReal$StringExponentPair
java.lang.System
-java.lang.SystemProperties
java.lang.Thread
java.lang.Thread$State
java.lang.Thread$UncaughtExceptionHandler
@@ -1100,15 +1413,18 @@
java.lang.ThreadLocal
java.lang.ThreadLocal$Values
java.lang.Throwable
+java.lang.TypeNotPresentException
java.lang.UnsafeByteSequence
java.lang.UnsatisfiedLinkError
java.lang.UnsupportedOperationException
java.lang.VMClassLoader
java.lang.VMThread
+java.lang.VerifyError
java.lang.VirtualMachineError
java.lang.Void
java.lang.annotation.Annotation
-java.lang.ref.PhantomReference
+java.lang.ref.FinalizerReference
+java.lang.ref.FinalizerReference$Sentinel
java.lang.ref.Reference
java.lang.ref.ReferenceQueue
java.lang.ref.SoftReference
@@ -1118,6 +1434,7 @@
java.lang.reflect.Array
java.lang.reflect.Constructor
java.lang.reflect.Field
+java.lang.reflect.Field$1
java.lang.reflect.GenericDeclaration
java.lang.reflect.InvocationHandler
java.lang.reflect.Member
@@ -1125,46 +1442,39 @@
java.lang.reflect.Method$1
java.lang.reflect.Modifier
java.lang.reflect.Proxy
-java.lang.reflect.ReflectionAccessImpl
java.lang.reflect.Type
java.math.BigDecimal
java.math.BigInt
java.math.BigInteger
+java.math.Multiplication
java.math.NativeBN
java.math.RoundingMode
java.net.AddressCache
-java.net.AddressCache$1
java.net.AddressCache$AddressCacheEntry
java.net.ContentHandler
-java.net.DatagramPacket
java.net.HttpURLConnection
java.net.Inet4Address
+java.net.Inet6Address
java.net.InetAddress
-java.net.InetAddress$1
-java.net.InetAddress$WaitReachable
java.net.InetSocketAddress
-java.net.InterfaceAddress
java.net.JarURLConnection
-java.net.MulticastGroupRequest
-java.net.NetPermission
-java.net.NetworkInterface
+java.net.PlainSocketImpl
java.net.Proxy
java.net.Proxy$Type
java.net.ProxySelector
java.net.ProxySelectorImpl
java.net.Socket
java.net.SocketAddress
-java.net.SocketException
java.net.SocketImpl
-java.net.SocketImplFactory
java.net.SocketOptions
-java.net.SocketTimeoutException
java.net.URI
-java.net.URIEncoderDecoder
+java.net.URI$1
+java.net.URI$PartEncoder
java.net.URL
java.net.URLConnection
java.net.URLConnection$DefaultContentHandler
java.net.URLEncoder
+java.net.URLEncoder$1
java.net.URLStreamHandler
java.nio.BaseByteBuffer
java.nio.Buffer
@@ -1182,11 +1492,9 @@
java.nio.ReadWriteCharArrayBuffer
java.nio.ReadWriteDirectByteBuffer
java.nio.ReadWriteHeapByteBuffer
-java.nio.WriteOnlyFileChannel
java.nio.channels.ByteChannel
java.nio.channels.Channel
java.nio.channels.FileChannel
-java.nio.channels.FileChannel$MapMode
java.nio.channels.GatheringByteChannel
java.nio.channels.InterruptibleChannel
java.nio.channels.ReadableByteChannel
@@ -1195,54 +1503,83 @@
java.nio.channels.spi.AbstractInterruptibleChannel
java.nio.channels.spi.AbstractInterruptibleChannel$1
java.nio.charset.Charset
-java.nio.charset.Charset$1
java.nio.charset.CharsetDecoder
+java.nio.charset.CharsetDecoderICU
java.nio.charset.CharsetEncoder
+java.nio.charset.CharsetEncoderICU
+java.nio.charset.CharsetICU
java.nio.charset.Charsets
java.nio.charset.CoderResult
java.nio.charset.CodingErrorAction
java.nio.charset.ModifiedUtf8
-java.security.AccessControlContext
java.security.AccessController
java.security.BasicPermission
+java.security.GeneralSecurityException
java.security.Guard
java.security.Key
+java.security.KeyFactory
+java.security.KeyFactorySpi
java.security.KeyStore
-java.security.KeyStore$1
java.security.KeyStoreSpi
+java.security.MessageDigest
+java.security.MessageDigestSpi
+java.security.NoSuchAlgorithmException
java.security.Permission
java.security.Principal
java.security.PrivilegedAction
-java.security.PrivilegedExceptionAction
-java.security.ProtectionDomain
java.security.Provider
java.security.Provider$Service
-java.security.Provider$Service$1
+java.security.PublicKey
java.security.SecureRandom
java.security.SecureRandomSpi
java.security.Security
-java.security.Security$1
java.security.Security$SecurityDoor
+java.security.Signature
+java.security.Signature$SignatureImpl
+java.security.SignatureSpi
+java.security.cert.CertPath
java.security.cert.CertPathParameters
java.security.cert.CertPathValidator
+java.security.cert.CertPathValidatorResult
java.security.cert.CertPathValidatorSpi
+java.security.cert.CertSelector
java.security.cert.Certificate
java.security.cert.CertificateFactory
java.security.cert.CertificateFactorySpi
+java.security.cert.PKIXCertPathValidatorResult
java.security.cert.PKIXParameters
+java.security.cert.PolicyNode
java.security.cert.TrustAnchor
+java.security.cert.X509CertSelector
java.security.cert.X509Certificate
java.security.cert.X509Extension
+java.security.interfaces.DSAKey
+java.security.interfaces.DSAPublicKey
+java.security.interfaces.RSAKey
+java.security.interfaces.RSAPublicKey
+java.security.spec.EncodedKeySpec
java.security.spec.KeySpec
+java.security.spec.RSAPublicKeySpec
+java.security.spec.X509EncodedKeySpec
+java.text.AttributedCharacterIterator$Attribute
+java.text.Bidi
+java.text.Bidi$Run
+java.text.BreakIterator
+java.text.CharacterIterator
java.text.DateFormat
java.text.DateFormatSymbols
java.text.DecimalFormat
java.text.DecimalFormat$1
java.text.DecimalFormatSymbols
+java.text.FieldPosition
java.text.Format
+java.text.Format$Field
java.text.NumberFormat
+java.text.NumberFormat$Field
java.text.ParsePosition
+java.text.RuleBasedBreakIterator
java.text.SimpleDateFormat
+java.text.StringCharacterIterator
java.util.AbstractCollection
java.util.AbstractList
java.util.AbstractList$FullListIterator
@@ -1256,10 +1593,11 @@
java.util.ArrayList$ArrayListIterator
java.util.Arrays
java.util.Arrays$ArrayList
-java.util.BitSet
java.util.Calendar
java.util.Collection
java.util.Collections
+java.util.Collections$1
+java.util.Collections$2
java.util.Collections$EmptyList
java.util.Collections$EmptyMap
java.util.Collections$EmptySet
@@ -1277,7 +1615,6 @@
java.util.Deque
java.util.Dictionary
java.util.EnumMap
-java.util.EnumSet
java.util.Enumeration
java.util.EventObject
java.util.Formattable
@@ -1306,6 +1643,7 @@
java.util.Hashtable$Values
java.util.Iterator
java.util.LinkedHashMap
+java.util.LinkedHashMap$EntryIterator
java.util.LinkedHashMap$KeyIterator
java.util.LinkedHashMap$LinkedEntry
java.util.LinkedHashMap$LinkedHashIterator
@@ -1321,7 +1659,6 @@
java.util.NavigableMap
java.util.NavigableSet
java.util.Properties
-java.util.PropertyPermission
java.util.Queue
java.util.Random
java.util.RandomAccess
@@ -1341,6 +1678,8 @@
java.util.TreeMap$Bound$3
java.util.TreeMap$EntrySet
java.util.TreeMap$EntrySet$1
+java.util.TreeMap$KeySet
+java.util.TreeMap$KeySet$1
java.util.TreeMap$MapIterator
java.util.TreeMap$Node
java.util.TreeMap$Relation
@@ -1349,11 +1688,17 @@
java.util.Vector$1
java.util.WeakHashMap
java.util.WeakHashMap$Entry
+java.util.WeakHashMap$Entry$Type
+java.util.WeakHashMap$HashIterator
java.util.concurrent.AbstractExecutorService
java.util.concurrent.BlockingQueue
java.util.concurrent.Callable
+java.util.concurrent.ConcurrentHashMap
+java.util.concurrent.ConcurrentHashMap$HashEntry
+java.util.concurrent.ConcurrentHashMap$Segment
java.util.concurrent.ConcurrentLinkedQueue
java.util.concurrent.ConcurrentLinkedQueue$Node
+java.util.concurrent.ConcurrentMap
java.util.concurrent.CopyOnWriteArrayList
java.util.concurrent.CopyOnWriteArrayList$CowIterator
java.util.concurrent.CountDownLatch
@@ -1400,6 +1745,7 @@
java.util.concurrent.locks.ReentrantLock$NonfairSync
java.util.concurrent.locks.ReentrantLock$Sync
java.util.concurrent.locks.ReentrantReadWriteLock
+java.util.concurrent.locks.ReentrantReadWriteLock$NonfairSync
java.util.concurrent.locks.ReentrantReadWriteLock$ReadLock
java.util.concurrent.locks.ReentrantReadWriteLock$Sync
java.util.concurrent.locks.ReentrantReadWriteLock$Sync$ThreadLocalHoldCounter
@@ -1420,9 +1766,6 @@
java.util.logging.Level
java.util.logging.LogManager
java.util.logging.LogManager$1
-java.util.logging.LogManager$2
-java.util.logging.LogManager$2$1
-java.util.logging.LogManager$4
java.util.logging.Logger
java.util.logging.Logger$1
java.util.logging.LoggingPermission
@@ -1437,12 +1780,13 @@
java.util.zip.CRC32
java.util.zip.Checksum
java.util.zip.Deflater
+java.util.zip.GZIPInputStream
java.util.zip.Inflater
java.util.zip.InflaterInputStream
java.util.zip.ZipConstants
java.util.zip.ZipEntry
java.util.zip.ZipFile
-java.util.zip.ZipFile$2
+java.util.zip.ZipFile$1
java.util.zip.ZipFile$RAFStream
java.util.zip.ZipFile$ZipInflaterInputStream
javax.microedition.khronos.egl.EGL
@@ -1463,30 +1807,19 @@
javax.net.ssl.HttpsURLConnection
javax.net.ssl.KeyManager
javax.net.ssl.KeyManagerFactory
-javax.net.ssl.KeyManagerFactory$1
javax.net.ssl.KeyManagerFactorySpi
javax.net.ssl.SSLContextSpi
+javax.net.ssl.SSLSession
javax.net.ssl.SSLSessionContext
javax.net.ssl.SSLSocket
javax.net.ssl.SSLSocketFactory
-javax.net.ssl.SSLSocketFactory$1
javax.net.ssl.TrustManager
javax.net.ssl.TrustManagerFactory
-javax.net.ssl.TrustManagerFactory$1
javax.net.ssl.TrustManagerFactorySpi
javax.net.ssl.X509ExtendedKeyManager
javax.net.ssl.X509KeyManager
javax.net.ssl.X509TrustManager
javax.security.auth.x500.X500Principal
-libcore.base.CollectionUtils
-libcore.base.CollectionUtils$1
-libcore.base.CollectionUtils$1$1
-libcore.base.EmptyArray
-libcore.base.Objects
-libcore.base.Streams
-libcore.icu.CharsetDecoderICU
-libcore.icu.CharsetEncoderICU
-libcore.icu.CharsetICU
libcore.icu.ErrorCode
libcore.icu.ICU
libcore.icu.LocaleData
@@ -1499,59 +1832,82 @@
libcore.icu.NativeNormalizer
libcore.icu.NativePluralRules
libcore.icu.TimeZones
-libcore.icu.TimeZones$CachedTimeZones
+libcore.internal.StringPool
+libcore.io.AsynchronousCloseMonitor
+libcore.io.Base64
+libcore.io.BlockGuardOs
libcore.io.BufferIterator
+libcore.io.ErrnoException
+libcore.io.ForwardingOs
+libcore.io.GaiException
libcore.io.HeapBufferIterator
+libcore.io.IoBridge
libcore.io.IoUtils
+libcore.io.Libcore
+libcore.io.Memory
libcore.io.MemoryMappedFile
libcore.io.NioBufferIterator
-libcore.math.MathUtils
+libcore.io.Os
+libcore.io.OsConstants
+libcore.io.Posix
+libcore.io.Streams
+libcore.io.StructAddrinfo
+libcore.io.StructFlock
+libcore.io.StructGroupReq
+libcore.io.StructLinger
+libcore.io.StructPasswd
+libcore.io.StructPollfd
+libcore.io.StructStat
+libcore.io.StructStatFs
+libcore.io.StructTimeval
+libcore.io.StructUtsname
libcore.net.MimeUtils
libcore.net.RawSocket
+libcore.net.UriCodec
+libcore.net.url.FileHandler
+libcore.net.url.FileURLConnection
+libcore.net.url.JarHandler
+libcore.net.url.JarURLConnectionImpl
+libcore.net.url.JarURLConnectionImpl$JarURLConnectionInputStream
+libcore.net.url.UrlUtils
+libcore.util.BasicLruCache
+libcore.util.CollectionUtils
+libcore.util.CollectionUtils$1
+libcore.util.CollectionUtils$1$1
+libcore.util.EmptyArray
+libcore.util.MutableInt
+libcore.util.MutableLong
+libcore.util.Objects
+libcore.util.ZoneInfo
+libcore.util.ZoneInfoDB
org.apache.commons.logging.Log
org.apache.commons.logging.LogFactory
org.apache.commons.logging.impl.Jdk14Logger
org.apache.commons.logging.impl.WeakHashtable
-org.apache.harmony.archive.util.Util
org.apache.harmony.dalvik.NativeTestTarget
org.apache.harmony.dalvik.ddmc.Chunk
org.apache.harmony.dalvik.ddmc.ChunkHandler
org.apache.harmony.dalvik.ddmc.DdmServer
-org.apache.harmony.kernel.vm.LangAccess
-org.apache.harmony.kernel.vm.ReflectionAccess
org.apache.harmony.lang.annotation.AnnotationFactory
org.apache.harmony.lang.annotation.AnnotationMember
-org.apache.harmony.luni.internal.net.www.protocol.file.FileURLConnection
-org.apache.harmony.luni.internal.net.www.protocol.file.Handler
-org.apache.harmony.luni.internal.net.www.protocol.jar.Handler
-org.apache.harmony.luni.internal.net.www.protocol.jar.JarURLConnectionImpl
-org.apache.harmony.luni.internal.net.www.protocol.jar.JarURLConnectionImpl$JarURLConnectionInputStream
org.apache.harmony.luni.internal.util.TimezoneGetter
-org.apache.harmony.luni.internal.util.ZoneInfo
-org.apache.harmony.luni.internal.util.ZoneInfoDB
-org.apache.harmony.luni.net.PlainSocketImpl
-org.apache.harmony.luni.net.SocketInputStream
-org.apache.harmony.luni.net.SocketOutputStream
-org.apache.harmony.luni.platform.IFileSystem
-org.apache.harmony.luni.platform.INetworkSystem
-org.apache.harmony.luni.platform.OSFileSystem
-org.apache.harmony.luni.platform.OSMemory
-org.apache.harmony.luni.platform.OSNetworkSystem
-org.apache.harmony.luni.platform.Platform
-org.apache.harmony.luni.util.FloatingPointParser
-org.apache.harmony.luni.util.FloatingPointParser$StringExponentPair
-org.apache.harmony.luni.util.PriviAction
org.apache.harmony.luni.util.TwoKeyHashMap
org.apache.harmony.luni.util.TwoKeyHashMap$Entry
org.apache.harmony.luni.util.TwoKeyHashMap$EntryIteratorImpl
org.apache.harmony.luni.util.TwoKeyHashMap$ValueIteratorImpl
org.apache.harmony.luni.util.TwoKeyHashMap$ValuesCollectionImpl
-org.apache.harmony.luni.util.Util
-org.apache.harmony.security.Util
org.apache.harmony.security.asn1.ASN1Any
+org.apache.harmony.security.asn1.ASN1BitString
+org.apache.harmony.security.asn1.ASN1BitString$ASN1NamedBitList
+org.apache.harmony.security.asn1.ASN1Boolean
org.apache.harmony.security.asn1.ASN1Choice
org.apache.harmony.security.asn1.ASN1Constants
-org.apache.harmony.security.asn1.ASN1Constructured
+org.apache.harmony.security.asn1.ASN1Constructed
+org.apache.harmony.security.asn1.ASN1Explicit
+org.apache.harmony.security.asn1.ASN1GeneralizedTime
+org.apache.harmony.security.asn1.ASN1Implicit
+org.apache.harmony.security.asn1.ASN1Integer
+org.apache.harmony.security.asn1.ASN1OctetString
org.apache.harmony.security.asn1.ASN1Oid
org.apache.harmony.security.asn1.ASN1Oid$1
org.apache.harmony.security.asn1.ASN1Primitive
@@ -1566,26 +1922,34 @@
org.apache.harmony.security.asn1.ASN1StringType$5
org.apache.harmony.security.asn1.ASN1StringType$6
org.apache.harmony.security.asn1.ASN1StringType$7
+org.apache.harmony.security.asn1.ASN1Time
org.apache.harmony.security.asn1.ASN1Type
org.apache.harmony.security.asn1.ASN1TypeCollection
+org.apache.harmony.security.asn1.ASN1UTCTime
org.apache.harmony.security.asn1.ASN1ValueCollection
org.apache.harmony.security.asn1.BerInputStream
+org.apache.harmony.security.asn1.BerOutputStream
+org.apache.harmony.security.asn1.BitString
org.apache.harmony.security.asn1.DerInputStream
+org.apache.harmony.security.asn1.DerOutputStream
+org.apache.harmony.security.asn1.ObjectIdentifier
org.apache.harmony.security.fortress.Engine
org.apache.harmony.security.fortress.Engine$ServiceCacheEntry
org.apache.harmony.security.fortress.Engine$SpiAndProvider
org.apache.harmony.security.fortress.SecurityAccess
-org.apache.harmony.security.fortress.SecurityUtils
org.apache.harmony.security.fortress.Services
-org.apache.harmony.security.fortress.Services$1
+org.apache.harmony.security.pkcs7.ContentInfo
+org.apache.harmony.security.pkcs7.ContentInfo$1
org.apache.harmony.security.provider.cert.Cache
org.apache.harmony.security.provider.cert.DRLCertFactory
-org.apache.harmony.security.provider.cert.DRLCertFactory$1
org.apache.harmony.security.provider.cert.X509CertFactoryImpl
+org.apache.harmony.security.provider.cert.X509CertImpl
+org.apache.harmony.security.provider.cert.X509CertPathImpl
+org.apache.harmony.security.provider.cert.X509CertPathImpl$1
+org.apache.harmony.security.provider.cert.X509CertPathImpl$2
+org.apache.harmony.security.provider.cert.X509CertPathImpl$3
org.apache.harmony.security.provider.crypto.CryptoProvider
-org.apache.harmony.security.provider.crypto.CryptoProvider$1
org.apache.harmony.security.provider.crypto.RandomBitsSupplier
-org.apache.harmony.security.provider.crypto.RandomBitsSupplier$1
org.apache.harmony.security.provider.crypto.SHA1PRNG_SecureRandomImpl
org.apache.harmony.security.provider.crypto.SHA1_Data
org.apache.harmony.security.utils.AlgNameMapper
@@ -1599,53 +1963,89 @@
org.apache.harmony.security.x501.DirectoryString$1
org.apache.harmony.security.x501.Name
org.apache.harmony.security.x501.Name$1
+org.apache.harmony.security.x509.AlgorithmIdentifier
+org.apache.harmony.security.x509.AlgorithmIdentifier$1
+org.apache.harmony.security.x509.BasicConstraints
+org.apache.harmony.security.x509.BasicConstraints$1
+org.apache.harmony.security.x509.Certificate
+org.apache.harmony.security.x509.Certificate$1
+org.apache.harmony.security.x509.EDIPartyName
+org.apache.harmony.security.x509.EDIPartyName$1
+org.apache.harmony.security.x509.Extension
+org.apache.harmony.security.x509.Extension$1
+org.apache.harmony.security.x509.Extension$2
+org.apache.harmony.security.x509.ExtensionValue
+org.apache.harmony.security.x509.Extensions
+org.apache.harmony.security.x509.Extensions$1
org.apache.harmony.security.x509.GeneralName
-org.apache.harmony.text.BidiRun
-org.apache.harmony.text.NativeBidi
+org.apache.harmony.security.x509.GeneralName$1
+org.apache.harmony.security.x509.GeneralNames
+org.apache.harmony.security.x509.GeneralNames$1
+org.apache.harmony.security.x509.KeyUsage
+org.apache.harmony.security.x509.ORAddress
+org.apache.harmony.security.x509.ORAddress$1
+org.apache.harmony.security.x509.ORAddress$2
+org.apache.harmony.security.x509.OtherName
+org.apache.harmony.security.x509.OtherName$1
+org.apache.harmony.security.x509.SubjectPublicKeyInfo
+org.apache.harmony.security.x509.SubjectPublicKeyInfo$1
+org.apache.harmony.security.x509.TBSCertificate
+org.apache.harmony.security.x509.TBSCertificate$1
+org.apache.harmony.security.x509.Time
+org.apache.harmony.security.x509.Time$1
+org.apache.harmony.security.x509.Validity
+org.apache.harmony.security.x509.Validity$1
org.apache.harmony.xml.ExpatAttributes
org.apache.harmony.xml.ExpatParser
-org.apache.harmony.xml.ExpatParser$ClonedAttributes
-org.apache.harmony.xml.ExpatParser$CurrentAttributes
-org.apache.harmony.xml.ExpatParser$ExpatLocator
-org.apache.harmony.xml.ExpatPullParser
-org.apache.harmony.xml.ExpatPullParser$ByteDocument
-org.apache.harmony.xml.ExpatPullParser$Document
-org.apache.harmony.xml.ExpatPullParser$Document$SaxHandler
-org.apache.harmony.xml.ExpatPullParser$EndTagEvent
-org.apache.harmony.xml.ExpatPullParser$Event
-org.apache.harmony.xml.ExpatPullParser$NamespaceStack
-org.apache.harmony.xml.ExpatPullParser$NamespaceStack$Builder
-org.apache.harmony.xml.ExpatPullParser$StartDocumentEvent
-org.apache.harmony.xml.ExpatPullParser$StartTagEvent
-org.apache.harmony.xml.ExpatPullParser$TextEvent
-org.apache.harmony.xml.ExpatReader
org.apache.harmony.xnet.provider.jsse.AbstractSessionContext
org.apache.harmony.xnet.provider.jsse.AbstractSessionContext$1
+org.apache.harmony.xnet.provider.jsse.ByteArray
org.apache.harmony.xnet.provider.jsse.ClientSessionContext
+org.apache.harmony.xnet.provider.jsse.ClientSessionContext$HostAndPort
org.apache.harmony.xnet.provider.jsse.DefaultSSLContextImpl
-org.apache.harmony.xnet.provider.jsse.IndexedPKIXParameters
+org.apache.harmony.xnet.provider.jsse.FileClientSessionCache
+org.apache.harmony.xnet.provider.jsse.FileClientSessionCache$Impl
org.apache.harmony.xnet.provider.jsse.JSSEProvider
-org.apache.harmony.xnet.provider.jsse.JSSEProvider$1
org.apache.harmony.xnet.provider.jsse.KeyManagerFactoryImpl
-org.apache.harmony.xnet.provider.jsse.KeyManagerFactoryImpl$1
org.apache.harmony.xnet.provider.jsse.KeyManagerImpl
org.apache.harmony.xnet.provider.jsse.NativeCrypto
org.apache.harmony.xnet.provider.jsse.NativeCrypto$SSLHandshakeCallbacks
org.apache.harmony.xnet.provider.jsse.OpenSSLContextImpl
+org.apache.harmony.xnet.provider.jsse.OpenSSLMessageDigestJDK
+org.apache.harmony.xnet.provider.jsse.OpenSSLMessageDigestJDK$MD5
+org.apache.harmony.xnet.provider.jsse.OpenSSLMessageDigestJDK$SHA1
org.apache.harmony.xnet.provider.jsse.OpenSSLProvider
+org.apache.harmony.xnet.provider.jsse.OpenSSLSessionImpl
+org.apache.harmony.xnet.provider.jsse.OpenSSLSignature
+org.apache.harmony.xnet.provider.jsse.OpenSSLSignature$MD5RSA
+org.apache.harmony.xnet.provider.jsse.OpenSSLSignature$SHA1DSA
+org.apache.harmony.xnet.provider.jsse.OpenSSLSignature$SHA1RSA
+org.apache.harmony.xnet.provider.jsse.OpenSSLSignature$SHA256RSA
+org.apache.harmony.xnet.provider.jsse.OpenSSLSignature$SHA384RSA
+org.apache.harmony.xnet.provider.jsse.OpenSSLSignature$SHA512RSA
org.apache.harmony.xnet.provider.jsse.OpenSSLSocketFactoryImpl
org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl
+org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl$SSLInputStream
+org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl$SSLOutputStream
+org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImplWrapper
org.apache.harmony.xnet.provider.jsse.ProtocolVersion
+org.apache.harmony.xnet.provider.jsse.SSLClientSessionCache
org.apache.harmony.xnet.provider.jsse.SSLContextImpl
org.apache.harmony.xnet.provider.jsse.SSLParametersImpl
org.apache.harmony.xnet.provider.jsse.ServerSessionContext
org.apache.harmony.xnet.provider.jsse.TrustManagerFactoryImpl
-org.apache.harmony.xnet.provider.jsse.TrustManagerFactoryImpl$1
-org.apache.harmony.xnet.provider.jsse.TrustManagerFactoryImpl$2
org.apache.harmony.xnet.provider.jsse.TrustManagerImpl
+org.apache.harmony.xnet.provider.jsse.TrustedCertificateIndex
+org.apache.harmony.xnet.provider.jsse.TrustedCertificateKeyStoreSpi
+org.apache.harmony.xnet.provider.jsse.TrustedCertificateStore
+org.apache.harmony.xnet.provider.jsse.TrustedCertificateStore$1
+org.apache.harmony.xnet.provider.jsse.TrustedCertificateStore$2
+org.apache.harmony.xnet.provider.jsse.TrustedCertificateStore$3
+org.apache.harmony.xnet.provider.jsse.TrustedCertificateStore$CertSelector
org.apache.http.ConnectionReuseStrategy
org.apache.http.FormattedHeader
org.apache.http.Header
+org.apache.http.HeaderElement
org.apache.http.HeaderElementIterator
org.apache.http.HeaderIterator
org.apache.http.HttpClientConnection
@@ -1662,6 +2062,7 @@
org.apache.http.HttpResponseFactory
org.apache.http.HttpResponseInterceptor
org.apache.http.HttpVersion
+org.apache.http.NameValuePair
org.apache.http.ProtocolVersion
org.apache.http.ReasonPhraseCatalog
org.apache.http.RequestLine
@@ -1678,6 +2079,9 @@
org.apache.http.client.ResponseHandler
org.apache.http.client.UserTokenHandler
org.apache.http.client.methods.AbortableHttpRequest
+org.apache.http.client.methods.HttpEntityEnclosingRequestBase
+org.apache.http.client.methods.HttpGet
+org.apache.http.client.methods.HttpPost
org.apache.http.client.methods.HttpRequestBase
org.apache.http.client.methods.HttpUriRequest
org.apache.http.client.params.HttpClientParams
@@ -1701,6 +2105,7 @@
org.apache.http.conn.params.ConnManagerParams
org.apache.http.conn.params.ConnManagerParams$1
org.apache.http.conn.params.ConnPerRoute
+org.apache.http.conn.params.ConnPerRouteBean
org.apache.http.conn.params.ConnRoutePNames
org.apache.http.conn.params.ConnRouteParams
org.apache.http.conn.routing.BasicRouteDirector
@@ -1727,6 +2132,7 @@
org.apache.http.cookie.CookieSpecRegistry
org.apache.http.entity.AbstractHttpEntity
org.apache.http.entity.BasicHttpEntity
+org.apache.http.entity.ByteArrayEntity
org.apache.http.entity.ContentLengthStrategy
org.apache.http.entity.HttpEntityWrapper
org.apache.http.impl.AbstractHttpClientConnection
@@ -1749,6 +2155,7 @@
org.apache.http.impl.client.DefaultRequestDirector
org.apache.http.impl.client.DefaultTargetAuthenticationHandler
org.apache.http.impl.client.DefaultUserTokenHandler
+org.apache.http.impl.client.EntityEnclosingRequestWrapper
org.apache.http.impl.client.RequestWrapper
org.apache.http.impl.client.RoutedRequest
org.apache.http.impl.conn.AbstractClientConnAdapter
@@ -1787,7 +2194,9 @@
org.apache.http.impl.io.AbstractMessageWriter
org.apache.http.impl.io.AbstractSessionInputBuffer
org.apache.http.impl.io.AbstractSessionOutputBuffer
+org.apache.http.impl.io.ChunkedInputStream
org.apache.http.impl.io.ContentLengthInputStream
+org.apache.http.impl.io.ContentLengthOutputStream
org.apache.http.impl.io.HttpRequestWriter
org.apache.http.impl.io.HttpTransportMetricsImpl
org.apache.http.impl.io.SocketInputBuffer
@@ -1799,12 +2208,14 @@
org.apache.http.io.SessionOutputBuffer
org.apache.http.message.AbstractHttpMessage
org.apache.http.message.BasicHeader
+org.apache.http.message.BasicHeaderElement
org.apache.http.message.BasicHeaderElementIterator
org.apache.http.message.BasicHeaderValueParser
org.apache.http.message.BasicHttpResponse
org.apache.http.message.BasicLineFormatter
org.apache.http.message.BasicLineParser
org.apache.http.message.BasicListHeaderIterator
+org.apache.http.message.BasicNameValuePair
org.apache.http.message.BasicRequestLine
org.apache.http.message.BasicStatusLine
org.apache.http.message.BufferedHeader
@@ -1836,99 +2247,17 @@
org.apache.http.util.ByteArrayBuffer
org.apache.http.util.CharArrayBuffer
org.apache.http.util.LangUtils
-com.android.org.bouncycastle.asn1.ASN1Choice
-com.android.org.bouncycastle.asn1.ASN1Collection
-com.android.org.bouncycastle.asn1.ASN1Collection$ASN1CollectionEnumeration
-com.android.org.bouncycastle.asn1.ASN1Encodable
-com.android.org.bouncycastle.asn1.ASN1EncodableVector
-com.android.org.bouncycastle.asn1.ASN1InputStream
-com.android.org.bouncycastle.asn1.ASN1Null
-com.android.org.bouncycastle.asn1.ASN1Object
-com.android.org.bouncycastle.asn1.ASN1OctetString
-com.android.org.bouncycastle.asn1.ASN1OctetStringParser
-com.android.org.bouncycastle.asn1.ASN1OutputStream
-com.android.org.bouncycastle.asn1.ASN1Sequence
-com.android.org.bouncycastle.asn1.ASN1SequenceParser
-com.android.org.bouncycastle.asn1.ASN1Set
-com.android.org.bouncycastle.asn1.ASN1StreamParser
-com.android.org.bouncycastle.asn1.ASN1TaggedObject
-com.android.org.bouncycastle.asn1.ASN1TaggedObjectParser
-com.android.org.bouncycastle.asn1.BERTaggedObjectParser
-com.android.org.bouncycastle.asn1.DERBitString
-com.android.org.bouncycastle.asn1.DERBoolean
-com.android.org.bouncycastle.asn1.DEREncodable
-com.android.org.bouncycastle.asn1.DEREncodableVector
-com.android.org.bouncycastle.asn1.DERFactory
-com.android.org.bouncycastle.asn1.DERIA5String
-com.android.org.bouncycastle.asn1.DERInteger
-com.android.org.bouncycastle.asn1.DERNull
-com.android.org.bouncycastle.asn1.DERObject
-com.android.org.bouncycastle.asn1.DERObjectIdentifier
-com.android.org.bouncycastle.asn1.DEROctetString
-com.android.org.bouncycastle.asn1.DEROctetStringParser
-com.android.org.bouncycastle.asn1.DEROutputStream
-com.android.org.bouncycastle.asn1.DERPrintableString
-com.android.org.bouncycastle.asn1.DERSequence
-com.android.org.bouncycastle.asn1.DERSequenceParser
-com.android.org.bouncycastle.asn1.DERSet
-com.android.org.bouncycastle.asn1.DERString
-com.android.org.bouncycastle.asn1.DERT61String
-com.android.org.bouncycastle.asn1.DERTaggedObject
-com.android.org.bouncycastle.asn1.DERTags
-com.android.org.bouncycastle.asn1.DERUTCTime
-com.android.org.bouncycastle.asn1.DERUTF8String
-com.android.org.bouncycastle.asn1.DERUniversalString
-com.android.org.bouncycastle.asn1.DefiniteLengthInputStream
-com.android.org.bouncycastle.asn1.IndefiniteLengthInputStream
-com.android.org.bouncycastle.asn1.LimitedInputStream
-com.android.org.bouncycastle.asn1.OIDTokenizer
-com.android.org.bouncycastle.asn1.OrderedTable
-com.android.org.bouncycastle.asn1.bc.BCObjectIdentifiers
-com.android.org.bouncycastle.asn1.iana.IANAObjectIdentifiers
-com.android.org.bouncycastle.asn1.nist.NISTObjectIdentifiers
-com.android.org.bouncycastle.asn1.oiw.OIWObjectIdentifiers
-com.android.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers
-com.android.org.bouncycastle.asn1.x509.AlgorithmIdentifier
-com.android.org.bouncycastle.asn1.x509.BasicConstraints
-com.android.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo
-com.android.org.bouncycastle.asn1.x509.TBSCertificateStructure
-com.android.org.bouncycastle.asn1.x509.Time
-com.android.org.bouncycastle.asn1.x509.X509CertificateStructure
-com.android.org.bouncycastle.asn1.x509.X509Extension
-com.android.org.bouncycastle.asn1.x509.X509Extensions
-com.android.org.bouncycastle.asn1.x509.X509Name
-com.android.org.bouncycastle.asn1.x509.X509NameElementList
-com.android.org.bouncycastle.asn1.x509.X509ObjectIdentifiers
-com.android.org.bouncycastle.asn1.x9.X9ObjectIdentifiers
-com.android.org.bouncycastle.crypto.Digest
-com.android.org.bouncycastle.crypto.ExtendedDigest
-com.android.org.bouncycastle.crypto.Mac
-com.android.org.bouncycastle.crypto.digests.OpenSSLDigest
-com.android.org.bouncycastle.crypto.digests.OpenSSLDigest$MD5
-com.android.org.bouncycastle.crypto.digests.OpenSSLDigest$SHA1
-com.android.org.bouncycastle.crypto.macs.HMac
-com.android.org.bouncycastle.jce.ProviderConfigurationPermission
-com.android.org.bouncycastle.jce.interfaces.BCKeyStore
-com.android.org.bouncycastle.jce.interfaces.ConfigurableProvider
-com.android.org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier
-com.android.org.bouncycastle.jce.provider.BouncyCastleProvider
-com.android.org.bouncycastle.jce.provider.BouncyCastleProvider$1
-com.android.org.bouncycastle.jce.provider.JDKKeyStore
-com.android.org.bouncycastle.jce.provider.JDKKeyStore$StoreEntry
-com.android.org.bouncycastle.jce.provider.JDKX509CertificateFactory
-com.android.org.bouncycastle.jce.provider.PEMUtil
-com.android.org.bouncycastle.jce.provider.PKCS12BagAttributeCarrierImpl
-com.android.org.bouncycastle.jce.provider.PKIXCertPathValidatorSpi
-com.android.org.bouncycastle.jce.provider.ProviderUtil
-com.android.org.bouncycastle.jce.provider.X509CertificateObject
-com.android.org.bouncycastle.jce.provider.asymmetric.ECMappings
-com.android.org.bouncycastle.jce.provider.symmetric.AESMappings
-com.android.org.bouncycastle.util.Strings
-com.android.org.bouncycastle.util.io.Streams
+org.kxml2.io.KXmlParser
+org.kxml2.io.KXmlParser$ValueContext
org.xml.sax.Attributes
org.xml.sax.ContentHandler
+org.xml.sax.DTDHandler
+org.xml.sax.EntityResolver
+org.xml.sax.ErrorHandler
+org.xml.sax.InputSource
org.xml.sax.Locator
org.xml.sax.XMLReader
+org.xml.sax.helpers.DefaultHandler
org.xmlpull.v1.XmlPullParser
org.xmlpull.v1.XmlSerializer
sun.misc.Unsafe
diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java
index 6b64dd0..c11755b 100644
--- a/services/java/com/android/server/InputMethodManagerService.java
+++ b/services/java/com/android/server/InputMethodManagerService.java
@@ -619,10 +619,7 @@
}
void updateImeWindowStatusLocked() {
- if (mStatusBar != null) {
- mStatusBar.setImeWindowStatus(mCurToken, mImeWindowVis,
- mBackDisposition);
- }
+ setImeWindowStatus(mCurToken, mImeWindowVis, mBackDisposition);
}
@Override
@@ -995,6 +992,8 @@
sessionState.session.finishSession();
} catch (RemoteException e) {
Slog.w(TAG, "Session failed to close due to remote exception", e);
+ mImeWindowVis = 0;
+ updateImeWindowStatusLocked();
}
}
}
@@ -1121,6 +1120,7 @@
}
}
+ @SuppressWarnings("deprecation")
@Override
public void setImeWindowStatus(IBinder token, int vis, int backDisposition) {
int uid = Binder.getCallingUid();
@@ -2591,6 +2591,7 @@
}
// TODO: We should change the return type from List to List<Parcelable>
+ @SuppressWarnings("rawtypes")
@Override
public List getShortcutInputMethodsAndSubtypes() {
synchronized (mMethodMap) {
diff --git a/services/java/com/android/server/NetworkManagementService.java b/services/java/com/android/server/NetworkManagementService.java
index 06077dd..e72d09f 100644
--- a/services/java/com/android/server/NetworkManagementService.java
+++ b/services/java/com/android/server/NetworkManagementService.java
@@ -69,7 +69,8 @@
/**
* @hide
*/
-class NetworkManagementService extends INetworkManagementService.Stub implements Watchdog.Monitor {
+public class NetworkManagementService extends INetworkManagementService.Stub
+ implements Watchdog.Monitor {
private static final String TAG = "NetworkManagementService";
private static final boolean DBG = false;
private static final String NETD_TAG = "NetdConnector";
@@ -87,6 +88,12 @@
/** Path to {@code /proc/net/xt_qtaguid/iface_stat}. */
private final File mStatsXtIface;
+ /**
+ * Name representing {@link #setGlobalAlert(long)} limit when delivered to
+ * {@link INetworkManagementEventObserver#limitReached(String, String)}.
+ */
+ public static final String LIMIT_GLOBAL_ALERT = "globalAlert";
+
/** {@link #mStatsXtUid} headers. */
private static final String KEY_IFACE = "iface";
private static final String KEY_UID = "uid_tag_int";
@@ -1056,8 +1063,12 @@
Slog.w(TAG, "problem parsing stats row '" + line + "': " + e);
}
}
+ } catch (NullPointerException e) {
+ throw new IllegalStateException("problem parsing stats: " + e);
+ } catch (NumberFormatException e) {
+ throw new IllegalStateException("problem parsing stats: " + e);
} catch (IOException e) {
- Slog.w(TAG, "problem parsing stats: " + e);
+ throw new IllegalStateException("problem parsing stats: " + e);
} finally {
IoUtils.closeQuietly(reader);
}
@@ -1338,8 +1349,12 @@
Slog.w(TAG, "problem parsing stats row '" + line + "': " + e);
}
}
+ } catch (NullPointerException e) {
+ throw new IllegalStateException("problem parsing stats: " + e);
+ } catch (NumberFormatException e) {
+ throw new IllegalStateException("problem parsing stats: " + e);
} catch (IOException e) {
- Slog.w(TAG, "problem parsing stats: " + e);
+ throw new IllegalStateException("problem parsing stats: " + e);
} finally {
IoUtils.closeQuietly(reader);
}
diff --git a/services/java/com/android/server/TextServicesManagerService.java b/services/java/com/android/server/TextServicesManagerService.java
index 18ddabd..321274f 100644
--- a/services/java/com/android/server/TextServicesManagerService.java
+++ b/services/java/com/android/server/TextServicesManagerService.java
@@ -173,7 +173,7 @@
@Override
public SpellCheckerInfo getCurrentSpellChecker(String locale) {
synchronized (mSpellCheckerMap) {
- String curSpellCheckerId =
+ final String curSpellCheckerId =
Settings.Secure.getString(mContext.getContentResolver(),
Settings.Secure.SELECTED_SPELL_CHECKER);
if (DBG) {
@@ -197,10 +197,16 @@
Slog.w(TAG, "getCurrentSpellChecker: " + subtypeHashCodeStr);
}
final SpellCheckerInfo sci = getCurrentSpellChecker(null);
- if (sci.getSubtypeCount() == 0) {
+ if (sci == null || sci.getSubtypeCount() == 0) {
+ if (DBG) {
+ Slog.w(TAG, "Subtype not found.");
+ }
return null;
}
if (TextUtils.isEmpty(subtypeHashCodeStr)) {
+ if (DBG) {
+ Slog.w(TAG, "Return first subtype in " + sci.getId());
+ }
// Return the first Subtype if there is no settings for the current subtype.
return sci.getSubtypeAt(0);
}
@@ -208,9 +214,15 @@
for (int i = 0; i < sci.getSubtypeCount(); ++i) {
final SpellCheckerSubtype scs = sci.getSubtypeAt(i);
if (scs.hashCode() == hashCode) {
+ if (DBG) {
+ Slog.w(TAG, "Return subtype " + scs.hashCode());
+ }
return scs;
}
}
+ if (DBG) {
+ Slog.w(TAG, "Return first subtype in " + sci.getId());
+ }
return sci.getSubtypeAt(0);
}
}
@@ -283,6 +295,13 @@
return;
}
+ @Override
+ public boolean isSpellCheckerEnabled() {
+ synchronized(mSpellCheckerMap) {
+ return isSpellCheckerEnabledLocked();
+ }
+ }
+
private void startSpellCheckerServiceInnerLocked(SpellCheckerInfo info, String locale,
ITextServicesSessionListener tsListener, ISpellCheckerSessionListener scListener,
int uid, Bundle bundle) {
@@ -354,7 +373,21 @@
"Requires permission "
+ android.Manifest.permission.WRITE_SECURE_SETTINGS);
}
- setCurrentSpellCheckerLocked(hashCode);
+ setCurrentSpellCheckerSubtypeLocked(hashCode);
+ }
+ }
+
+ @Override
+ public void setSpellCheckerEnabled(boolean enabled) {
+ synchronized(mSpellCheckerMap) {
+ if (mContext.checkCallingOrSelfPermission(
+ android.Manifest.permission.WRITE_SECURE_SETTINGS)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException(
+ "Requires permission "
+ + android.Manifest.permission.WRITE_SECURE_SETTINGS);
+ }
+ setSpellCheckerEnabledLocked(enabled);
}
}
@@ -372,7 +405,7 @@
}
}
- private void setCurrentSpellCheckerLocked(int hashCode) {
+ private void setCurrentSpellCheckerSubtypeLocked(int hashCode) {
if (DBG) {
Slog.w(TAG, "setCurrentSpellCheckerSubtype: " + hashCode);
}
@@ -397,6 +430,33 @@
}
}
+ private void setSpellCheckerEnabledLocked(boolean enabled) {
+ if (DBG) {
+ Slog.w(TAG, "setSpellCheckerEnabled: " + enabled);
+ }
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.SPELL_CHECKER_ENABLED, enabled ? 1 : 0);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
+ private boolean isSpellCheckerEnabledLocked() {
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ final boolean retval = Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.SPELL_CHECKER_ENABLED, 1) == 1;
+ if (DBG) {
+ Slog.w(TAG, "getSpellCheckerEnabled: " + retval);
+ }
+ return retval;
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
// SpellCheckerBindGroup contains active text service session listeners.
// If there are no listeners anymore, the SpellCheckerBindGroup instance will be removed from
// mSpellCheckerBindGroups
diff --git a/services/java/com/android/server/ThrottleService.java b/services/java/com/android/server/ThrottleService.java
index 24b6ac3..2155147 100644
--- a/services/java/com/android/server/ThrottleService.java
+++ b/services/java/com/android/server/ThrottleService.java
@@ -532,9 +532,12 @@
mLastRead = 0;
mLastWrite = 0;
}
+ } catch (IllegalStateException e) {
+ Slog.e(TAG, "problem during onPollAlarm: " + e);
} catch (RemoteException e) {
- Slog.e(TAG, "got remoteException in onPollAlarm:" + e);
+ Slog.e(TAG, "problem during onPollAlarm: " + e);
}
+
// don't count this data if we're roaming.
boolean roaming = "true".equals(
SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_ISROAMING));
diff --git a/services/java/com/android/server/WallpaperManagerService.java b/services/java/com/android/server/WallpaperManagerService.java
index 9765f2a..6ceccaf 100644
--- a/services/java/com/android/server/WallpaperManagerService.java
+++ b/services/java/com/android/server/WallpaperManagerService.java
@@ -75,7 +75,7 @@
static final String TAG = "WallpaperService";
static final boolean DEBUG = false;
- Object mLock = new Object();
+ final Object mLock = new Object[0];
/**
* Minimum time between crashes of a wallpaper service for us to consider
@@ -118,9 +118,10 @@
File changedFile = new File(WALLPAPER_DIR, path);
if (WALLPAPER_FILE.equals(changedFile)) {
notifyCallbacksLocked();
- if (mWallpaperComponent == null ||
- mWallpaperComponent.equals(mImageWallpaperComponent)) {
- bindWallpaperComponentLocked(mWallpaperComponent, true);
+ if (mWallpaperComponent == null || mImageWallpaperPending) {
+ mImageWallpaperPending = false;
+ bindWallpaperComponentLocked(mImageWallpaperComponent, true);
+ saveSettingsLocked();
}
}
}
@@ -133,7 +134,12 @@
int mWidth = -1;
int mHeight = -1;
-
+
+ /**
+ * Client is currently writing a new image wallpaper.
+ */
+ boolean mImageWallpaperPending;
+
/**
* Resource name if using a picture from the wallpaper gallery
*/
@@ -343,6 +349,7 @@
}
final long ident = Binder.clearCallingIdentity();
try {
+ mImageWallpaperPending = false;
bindWallpaperComponentLocked(null, false);
} catch (IllegalArgumentException e) {
// This can happen if the default wallpaper component doesn't
@@ -433,9 +440,7 @@
try {
ParcelFileDescriptor pfd = updateWallpaperBitmapLocked(name);
if (pfd != null) {
- // Bind the wallpaper to an ImageWallpaper
- bindWallpaperComponentLocked(mImageWallpaperComponent, false);
- saveSettingsLocked();
+ mImageWallpaperPending = true;
}
return pfd;
} finally {
@@ -463,6 +468,7 @@
synchronized (mLock) {
final long ident = Binder.clearCallingIdentity();
try {
+ mImageWallpaperPending = false;
bindWallpaperComponentLocked(name, false);
} finally {
Binder.restoreCallingIdentity(ident);
diff --git a/services/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
index af01c5b..09ddc2f 100644
--- a/services/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -40,7 +40,6 @@
import android.os.Message;
import android.os.RemoteException;
import android.os.ServiceManager;
-import android.os.SystemClock;
import android.provider.Settings;
import android.text.TextUtils;
import android.text.TextUtils.SimpleStringSplitter;
@@ -72,7 +71,6 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.util.concurrent.atomic.AtomicInteger;
/**
* This class is instantiated by the system as a system level service and can be
@@ -871,10 +869,6 @@
boolean mIsAutomation;
- final Callback mCallback = new Callback();
-
- final AtomicInteger mInteractionIdCounter = new AtomicInteger();
-
final Rect mTempBounds = new Rect();
// the events pending events to be dispatched to this service
@@ -974,14 +968,16 @@
}
}
- public AccessibilityNodeInfo findAccessibilityNodeInfoByViewIdInActiveWindow(int viewId)
+ public float findAccessibilityNodeInfoByViewIdInActiveWindow(int viewId,
+ int interactionId, IAccessibilityInteractionConnectionCallback callback,
+ long interrogatingTid)
throws RemoteException {
IAccessibilityInteractionConnection connection = null;
synchronized (mLock) {
mSecurityPolicy.enforceCanRetrieveWindowContent(this);
final boolean permissionGranted = mSecurityPolicy.canRetrieveWindowContent(this);
if (!permissionGranted) {
- return null;
+ return 0;
} else {
connection = getConnectionToRetrievalAllowingWindowLocked();
if (connection == null) {
@@ -989,22 +985,15 @@
Slog.e(LOG_TAG, "No interaction connection to a retrieve "
+ "allowing window.");
}
- return null;
+ return 0;
}
}
}
+ final int interrogatingPid = Binder.getCallingPid();
final long identityToken = Binder.clearCallingIdentity();
try {
- final int interactionId = mInteractionIdCounter.getAndIncrement();
- connection.findAccessibilityNodeInfoByViewId(viewId, interactionId, mCallback);
- AccessibilityNodeInfo info = mCallback.getFindAccessibilityNodeInfoResultAndClear(
- interactionId);
- if (info != null) {
- applyCompatibilityScaleIfNeeded(info);
- info.setConnection(this);
- info.setSealed(true);
- }
- return info;
+ connection.findAccessibilityNodeInfoByViewId(viewId, interactionId, callback,
+ interrogatingPid, interrogatingTid);
} catch (RemoteException re) {
if (DEBUG) {
Slog.e(LOG_TAG, "Error finding node.");
@@ -1012,51 +1001,44 @@
} finally {
Binder.restoreCallingIdentity(identityToken);
}
- return null;
+ return getCompatibilityScale(mSecurityPolicy.getRetrievalAllowingWindowLocked());
}
- public List<AccessibilityNodeInfo> findAccessibilityNodeInfosByViewTextInActiveWindow(
- String text) throws RemoteException {
+ public float findAccessibilityNodeInfosByViewTextInActiveWindow(
+ String text, int interactionId,
+ IAccessibilityInteractionConnectionCallback callback, long threadId)
+ throws RemoteException {
return findAccessibilityNodeInfosByViewText(text,
- mSecurityPolicy.mRetrievalAlowingWindowId, View.NO_ID);
+ mSecurityPolicy.mRetrievalAlowingWindowId, View.NO_ID, interactionId, callback,
+ threadId);
}
- public List<AccessibilityNodeInfo> findAccessibilityNodeInfosByViewText(String text,
- int accessibilityWindowId, int accessibilityViewId) throws RemoteException {
+ public float findAccessibilityNodeInfosByViewText(String text,
+ int accessibilityWindowId, int accessibilityViewId, int interactionId,
+ IAccessibilityInteractionConnectionCallback callback, long interrogatingTid)
+ throws RemoteException {
IAccessibilityInteractionConnection connection = null;
synchronized (mLock) {
mSecurityPolicy.enforceCanRetrieveWindowContent(this);
final boolean permissionGranted =
mSecurityPolicy.canGetAccessibilityNodeInfoLocked(this, accessibilityWindowId);
if (!permissionGranted) {
- return null;
+ return 0;
} else {
connection = getConnectionToRetrievalAllowingWindowLocked();
if (connection == null) {
if (DEBUG) {
Slog.e(LOG_TAG, "No interaction connection to focused window.");
}
- return null;
+ return 0;
}
}
}
+ final int interrogatingPid = Binder.getCallingPid();
final long identityToken = Binder.clearCallingIdentity();
try {
- final int interactionId = mInteractionIdCounter.getAndIncrement();
connection.findAccessibilityNodeInfosByViewText(text, accessibilityViewId,
- interactionId, mCallback);
- List<AccessibilityNodeInfo> infos =
- mCallback.getFindAccessibilityNodeInfosResultAndClear(interactionId);
- if (infos != null) {
- final int infoCount = infos.size();
- for (int i = 0; i < infoCount; i++) {
- AccessibilityNodeInfo info = infos.get(i);
- applyCompatibilityScaleIfNeeded(info);
- info.setConnection(this);
- info.setSealed(true);
- }
- }
- return infos;
+ interactionId, callback, interrogatingPid, interrogatingTid);
} catch (RemoteException re) {
if (DEBUG) {
Slog.e(LOG_TAG, "Error finding node.");
@@ -1064,18 +1046,20 @@
} finally {
Binder.restoreCallingIdentity(identityToken);
}
- return null;
+ return getCompatibilityScale(accessibilityWindowId);
}
- public AccessibilityNodeInfo findAccessibilityNodeInfoByAccessibilityId(
- int accessibilityWindowId, int accessibilityViewId) throws RemoteException {
+ public float findAccessibilityNodeInfoByAccessibilityId(int accessibilityWindowId,
+ int accessibilityViewId, int interactionId,
+ IAccessibilityInteractionConnectionCallback callback, long interrogatingTid)
+ throws RemoteException {
IAccessibilityInteractionConnection connection = null;
synchronized (mLock) {
mSecurityPolicy.enforceCanRetrieveWindowContent(this);
final boolean permissionGranted =
mSecurityPolicy.canGetAccessibilityNodeInfoLocked(this, accessibilityWindowId);
if (!permissionGranted) {
- return null;
+ return 0;
} else {
connection = mWindowIdToInteractionConnectionMap.get(accessibilityWindowId);
if (connection == null) {
@@ -1083,23 +1067,15 @@
Slog.e(LOG_TAG, "No interaction connection to window: "
+ accessibilityWindowId);
}
- return null;
+ return 0;
}
}
}
+ final int interrogatingPid = Binder.getCallingPid();
final long identityToken = Binder.clearCallingIdentity();
try {
- final int interactionId = mInteractionIdCounter.getAndIncrement();
connection.findAccessibilityNodeInfoByAccessibilityId(accessibilityViewId,
- interactionId, mCallback);
- AccessibilityNodeInfo info =
- mCallback.getFindAccessibilityNodeInfoResultAndClear(interactionId);
- if (info != null) {
- applyCompatibilityScaleIfNeeded(info);
- info.setConnection(this);
- info.setSealed(true);
- }
- return info;
+ interactionId, callback, interrogatingPid, interrogatingTid);
} catch (RemoteException re) {
if (DEBUG) {
Slog.e(LOG_TAG, "Error requesting node with accessibilityViewId: "
@@ -1108,11 +1084,12 @@
} finally {
Binder.restoreCallingIdentity(identityToken);
}
- return null;
+ return getCompatibilityScale(accessibilityWindowId);
}
public boolean performAccessibilityAction(int accessibilityWindowId,
- int accessibilityViewId, int action) {
+ int accessibilityViewId, int action, int interactionId,
+ IAccessibilityInteractionConnectionCallback callback, long interrogatingTid) {
IAccessibilityInteractionConnection connection = null;
synchronized (mLock) {
final boolean permissionGranted = mSecurityPolicy.canPerformActionLocked(this,
@@ -1130,12 +1107,11 @@
}
}
}
+ final int interrogatingPid = Binder.getCallingPid();
final long identityToken = Binder.clearCallingIdentity();
try {
- final int interactionId = mInteractionIdCounter.getAndIncrement();
connection.performAccessibilityAction(accessibilityViewId, action, interactionId,
- mCallback);
- return mCallback.getPerformAccessibilityActionResult(interactionId);
+ callback, interrogatingPid, interrogatingTid);
} catch (RemoteException re) {
if (DEBUG) {
Slog.e(LOG_TAG, "Error requesting node with accessibilityViewId: "
@@ -1144,7 +1120,7 @@
} finally {
Binder.restoreCallingIdentity(identityToken);
}
- return false;
+ return true;
}
public void onServiceDisconnected(ComponentName componentName) {
@@ -1173,22 +1149,9 @@
return mWindowIdToInteractionConnectionMap.get(windowId);
}
- private void applyCompatibilityScaleIfNeeded(AccessibilityNodeInfo info) {
- IBinder windowToken = mWindowIdToWindowTokenMap.get(info.getWindowId());
- final float scale = mWindowManagerService.getWindowCompatibilityScale(windowToken);
-
- if (scale == 1.0f) {
- return;
- }
-
- Rect bounds = mTempBounds;
- info.getBoundsInParent(bounds);
- bounds.scale(scale);
- info.setBoundsInParent(bounds);
-
- info.getBoundsInScreen(bounds);
- bounds.scale(scale);
- info.setBoundsInScreen(bounds);
+ private float getCompatibilityScale(int windowId) {
+ IBinder windowToken = mWindowIdToWindowTokenMap.get(windowId);
+ return mWindowManagerService.getWindowCompatibilityScale(windowToken);
}
}
@@ -1275,99 +1238,4 @@
}
}
}
-
- final class Callback extends IAccessibilityInteractionConnectionCallback.Stub {
- private static final long TIMEOUT_INTERACTION_MILLIS = 5000;
-
- private int mInteractionId = -1;
- private AccessibilityNodeInfo mFindAccessibilityNodeInfoResult;
- private List<AccessibilityNodeInfo> mFindAccessibilityNodeInfosResult;
- private boolean mPerformAccessibilityActionResult;
-
- public void setFindAccessibilityNodeInfoResult(AccessibilityNodeInfo info,
- int interactionId) {
- synchronized (mLock) {
- if (interactionId > mInteractionId) {
- mFindAccessibilityNodeInfoResult = info;
- mInteractionId = interactionId;
- }
- mLock.notifyAll();
- }
- }
-
- public AccessibilityNodeInfo getFindAccessibilityNodeInfoResultAndClear(int interactionId) {
- synchronized (mLock) {
- waitForResultTimedLocked(TIMEOUT_INTERACTION_MILLIS, interactionId);
- AccessibilityNodeInfo result = mFindAccessibilityNodeInfoResult;
- clearLocked();
- return result;
- }
- }
-
- public void setFindAccessibilityNodeInfosResult(List<AccessibilityNodeInfo> infos,
- int interactionId) {
- synchronized (mLock) {
- if (interactionId > mInteractionId) {
- mFindAccessibilityNodeInfosResult = infos;
- mInteractionId = interactionId;
- }
- mLock.notifyAll();
- }
- }
-
- public List<AccessibilityNodeInfo> getFindAccessibilityNodeInfosResultAndClear(
- int interactionId) {
- synchronized (mLock) {
- waitForResultTimedLocked(TIMEOUT_INTERACTION_MILLIS, interactionId);
- List<AccessibilityNodeInfo> result = mFindAccessibilityNodeInfosResult;
- clearLocked();
- return result;
- }
- }
-
- public void setPerformAccessibilityActionResult(boolean succeeded, int interactionId) {
- synchronized (mLock) {
- if (interactionId > mInteractionId) {
- mPerformAccessibilityActionResult = succeeded;
- mInteractionId = interactionId;
- }
- mLock.notifyAll();
- }
- }
-
- public boolean getPerformAccessibilityActionResult(int interactionId) {
- synchronized (mLock) {
- waitForResultTimedLocked(TIMEOUT_INTERACTION_MILLIS, interactionId);
- final boolean result = mPerformAccessibilityActionResult;
- clearLocked();
- return result;
- }
- }
-
- public void clearLocked() {
- mInteractionId = -1;
- mFindAccessibilityNodeInfoResult = null;
- mFindAccessibilityNodeInfosResult = null;
- mPerformAccessibilityActionResult = false;
- }
-
- private void waitForResultTimedLocked(long waitTimeMillis, int interactionId) {
- final long startTimeMillis = SystemClock.uptimeMillis();
- while (true) {
- try {
- if (mInteractionId == interactionId) {
- return;
- }
- final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis;
- waitTimeMillis = TIMEOUT_INTERACTION_MILLIS - elapsedTimeMillis;
- if (waitTimeMillis <= 0) {
- return;
- }
- mLock.wait(waitTimeMillis);
- } catch (InterruptedException ie) {
- /* ignore */
- }
- }
- }
- }
}
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index c935733..7232a94 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -9026,6 +9026,7 @@
final static class MemItem {
final String label;
final long pss;
+ ArrayList<MemItem> subitems;
public MemItem(String _label, long _pss) {
label = _label;
@@ -9051,7 +9052,10 @@
for (int i=0; i<items.size(); i++) {
MemItem mi = items.get(i);
- pw.print(prefix); pw.printf("%8d Kb: ", mi.pss); pw.println(mi.label);
+ pw.print(prefix); pw.printf("%7d Kb: ", mi.pss); pw.println(mi.label);
+ if (mi.subitems != null) {
+ dumpMemItems(pw, prefix + " ", mi.subitems, true);
+ }
}
}
@@ -9119,6 +9123,7 @@
"Backup", "Services", "Home", "Background"
};
long oomPss[] = new long[oomLabel.length];
+ ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])new ArrayList[oomLabel.length];
long totalPss = 0;
@@ -9147,7 +9152,9 @@
if (!isCheckinRequest && mi != null) {
long myTotalPss = mi.getTotalPss();
totalPss += myTotalPss;
- procMems.add(new MemItem(r.processName + " (pid " + r.pid + ")", myTotalPss));
+ MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
+ myTotalPss);
+ procMems.add(pssItem);
nativePss += mi.nativePss;
dalvikPss += mi.dalvikPss;
@@ -9161,6 +9168,10 @@
for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
if (r.setAdj <= oomAdj[oomIndex] || oomIndex == (oomPss.length-1)) {
oomPss[oomIndex] += myTotalPss;
+ if (oomProcs[oomIndex] == null) {
+ oomProcs[oomIndex] = new ArrayList<MemItem>();
+ }
+ oomProcs[oomIndex].add(pssItem);
break;
}
}
@@ -9181,7 +9192,9 @@
ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
for (int j=0; j<oomPss.length; j++) {
if (oomPss[j] != 0) {
- oomMems.add(new MemItem(oomLabel[j], oomPss[j]));
+ MemItem item = new MemItem(oomLabel[j], oomPss[j]);
+ item.subitems = oomProcs[j];
+ oomMems.add(item);
}
}
diff --git a/services/java/com/android/server/net/NetworkPolicyManagerService.java b/services/java/com/android/server/net/NetworkPolicyManagerService.java
index 84880f9..84e5eae 100644
--- a/services/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -60,6 +60,7 @@
import static com.android.server.net.NetworkStatsService.ACTION_NETWORK_STATS_UPDATED;
import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
import static org.xmlpull.v1.XmlPullParser.START_TAG;
+import static com.android.server.NetworkManagementService.LIMIT_GLOBAL_ALERT;
import android.app.IActivityManager;
import android.app.INotificationManager;
@@ -454,7 +455,7 @@
mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
synchronized (mRulesLock) {
- if (mMeteredIfaces.contains(iface)) {
+ if (mMeteredIfaces.contains(iface) && !LIMIT_GLOBAL_ALERT.equals(limitName)) {
try {
// force stats update to make sure we have numbers that
// caused alert to trigger.
@@ -763,7 +764,12 @@
// disable data connection when over limit and not snoozed
final boolean overLimit = policy.limitBytes != LIMIT_DISABLED
&& totalBytes > policy.limitBytes && policy.lastSnooze < start;
- setNetworkTemplateEnabled(policy.template, !overLimit);
+ final boolean enabled = !overLimit;
+
+ if (LOGD) {
+ Slog.d(TAG, "setting template=" + policy.template + " enabled=" + enabled);
+ }
+ setNetworkTemplateEnabled(policy.template, enabled);
}
}
@@ -772,7 +778,6 @@
* for the given {@link NetworkTemplate}.
*/
private void setNetworkTemplateEnabled(NetworkTemplate template, boolean enabled) {
- if (LOGD) Slog.d(TAG, "setting template=" + template + " enabled=" + enabled);
switch (template.getMatchRule()) {
case MATCH_MOBILE_3G_LOWER:
case MATCH_MOBILE_4G:
diff --git a/services/java/com/android/server/net/NetworkStatsService.java b/services/java/com/android/server/net/NetworkStatsService.java
index c911687..80ae9bc 100644
--- a/services/java/com/android/server/net/NetworkStatsService.java
+++ b/services/java/com/android/server/net/NetworkStatsService.java
@@ -43,6 +43,7 @@
import static android.text.format.DateUtils.HOUR_IN_MILLIS;
import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
import static com.android.internal.util.Preconditions.checkNotNull;
+import static com.android.server.NetworkManagementService.LIMIT_GLOBAL_ALERT;
import static com.android.server.NetworkManagementSocketTagger.resetKernelUidStats;
import static com.android.server.NetworkManagementSocketTagger.setKernelCounterSet;
@@ -56,6 +57,7 @@
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.net.IConnectivityManager;
+import android.net.INetworkManagementEventObserver;
import android.net.INetworkStatsService;
import android.net.NetworkIdentity;
import android.net.NetworkInfo;
@@ -121,7 +123,8 @@
private static final int VERSION_UID_WITH_TAG = 3;
private static final int VERSION_UID_WITH_SET = 4;
- private static final int MSG_FORCE_UPDATE = 0x1;
+ private static final int MSG_PERFORM_POLL = 0x1;
+ private static final int MSG_PERFORM_POLL_DETAILED = 0x2;
private final Context mContext;
private final INetworkManagementService mNetworkManager;
@@ -141,7 +144,6 @@
private PendingIntent mPollIntent;
- // TODO: listen for kernel push events through netd instead of polling
// TODO: trim empty history objects entirely
private static final long KB_IN_BYTES = 1024;
@@ -174,17 +176,18 @@
/** Flag if {@link #mUidStats} have been loaded from disk. */
private boolean mUidStatsLoaded = false;
- private NetworkStats mLastNetworkSnapshot;
- private NetworkStats mLastPersistNetworkSnapshot;
+ private NetworkStats mLastPollNetworkSnapshot;
+ private NetworkStats mLastPollUidSnapshot;
+ private NetworkStats mLastPollOperationsSnapshot;
- private NetworkStats mLastUidSnapshot;
+ private NetworkStats mLastPersistNetworkSnapshot;
+ private NetworkStats mLastPersistUidSnapshot;
/** Current counter sets for each UID. */
private SparseIntArray mActiveUidCounterSet = new SparseIntArray();
/** 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;
@@ -252,13 +255,18 @@
mContext.registerReceiver(mShutdownReceiver, shutdownFilter);
try {
- registerPollAlarmLocked();
+ mNetworkManager.registerObserver(mAlertObserver);
} catch (RemoteException e) {
- Slog.w(TAG, "unable to register poll alarm");
+ // ouch, no push updates means we fall back to
+ // ACTION_NETWORK_STATS_POLL intervals.
+ Slog.e(TAG, "unable to register INetworkManagementEventObserver", e);
}
- // kick off background poll to bootstrap deltas
- mHandler.obtainMessage(MSG_FORCE_UPDATE).sendToTarget();
+ registerPollAlarmLocked();
+ registerGlobalAlert();
+
+ // bootstrap initial stats to prevent double-counting later
+ bootstrapStats();
}
private void shutdownLocked() {
@@ -280,17 +288,37 @@
* Clear any existing {@link #ACTION_NETWORK_STATS_POLL} alarms, and
* reschedule based on current {@link NetworkStatsSettings#getPollInterval()}.
*/
- private void registerPollAlarmLocked() throws RemoteException {
- if (mPollIntent != null) {
- mAlarmManager.remove(mPollIntent);
+ private void registerPollAlarmLocked() {
+ try {
+ if (mPollIntent != null) {
+ mAlarmManager.remove(mPollIntent);
+ }
+
+ mPollIntent = PendingIntent.getBroadcast(
+ mContext, 0, new Intent(ACTION_NETWORK_STATS_POLL), 0);
+
+ final long currentRealtime = SystemClock.elapsedRealtime();
+ mAlarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME, currentRealtime,
+ mSettings.getPollInterval(), mPollIntent);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "problem registering for poll alarm: " + e);
}
+ }
- mPollIntent = PendingIntent.getBroadcast(
- mContext, 0, new Intent(ACTION_NETWORK_STATS_POLL), 0);
-
- final long currentRealtime = SystemClock.elapsedRealtime();
- mAlarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME, currentRealtime,
- mSettings.getPollInterval(), mPollIntent);
+ /**
+ * Register for a global alert that is delivered through
+ * {@link INetworkManagementEventObserver} once a threshold amount of data
+ * has been transferred.
+ */
+ private void registerGlobalAlert() {
+ try {
+ final long alertBytes = mSettings.getPersistThreshold();
+ mNetworkManager.setGlobalAlert(alertBytes);
+ } catch (IllegalStateException e) {
+ Slog.w(TAG, "problem registering for global alert: " + e);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "problem registering for global alert: " + e);
+ }
}
@Override
@@ -475,10 +503,7 @@
@Override
public void forceUpdate() {
mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG);
-
- synchronized (mStatsLock) {
- performPollLocked(true, false);
- }
+ performPoll(true, false);
}
/**
@@ -507,14 +532,10 @@
public void onReceive(Context context, Intent intent) {
// on background handler thread, and verified UPDATE_DEVICE_STATS
// permission above.
- synchronized (mStatsLock) {
- mWakeLock.acquire();
- try {
- performPollLocked(true, false);
- } finally {
- mWakeLock.release();
- }
- }
+ performPoll(true, false);
+
+ // verify that we're watching global alert
+ registerGlobalAlert();
}
};
@@ -547,6 +568,26 @@
};
/**
+ * Observer that watches for {@link INetworkManagementService} alerts.
+ */
+ private INetworkManagementEventObserver mAlertObserver = new NetworkAlertObserver() {
+ @Override
+ public void limitReached(String limitName, String iface) {
+ // only someone like NMS should be calling us
+ mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
+
+ if (LIMIT_GLOBAL_ALERT.equals(limitName)) {
+ // kick off background poll to collect network stats; UID stats
+ // are handled during normal polling interval.
+ mHandler.obtainMessage(MSG_PERFORM_POLL).sendToTarget();
+
+ // re-arm global alert for next update
+ registerGlobalAlert();
+ }
+ }
+ };
+
+ /**
* Inspect all current {@link NetworkState} to derive mapping from {@code
* iface} to {@link NetworkStatsHistory}. When multiple {@link NetworkInfo}
* are active on a single {@code iface}, they are combined under a single
@@ -588,6 +629,33 @@
}
/**
+ * Bootstrap initial stats snapshot, usually during {@link #systemReady()}
+ * so we have baseline values without double-counting.
+ */
+ private void bootstrapStats() {
+ try {
+ mLastPollNetworkSnapshot = mNetworkManager.getNetworkStatsSummary();
+ mLastPollUidSnapshot = mNetworkManager.getNetworkStatsUidDetail(UID_ALL);
+ mLastPollOperationsSnapshot = new NetworkStats(0L, 0);
+ } catch (IllegalStateException e) {
+ Slog.w(TAG, "problem reading network stats: " + e);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "problem reading network stats: " + e);
+ }
+ }
+
+ private void performPoll(boolean detailedPoll, boolean forcePersist) {
+ synchronized (mStatsLock) {
+ mWakeLock.acquire();
+ try {
+ performPollLocked(detailedPoll, forcePersist);
+ } finally {
+ mWakeLock.release();
+ }
+ }
+ }
+
+ /**
* Periodic poll operation, reading current statistics and recording into
* {@link NetworkStatsHistory}.
*
@@ -596,6 +664,7 @@
*/
private void performPollLocked(boolean detailedPoll, boolean forcePersist) {
if (LOGV) Slog.v(TAG, "performPollLocked()");
+ final long startRealtime = SystemClock.elapsedRealtime();
// try refreshing time source when stale
if (mTime.getCacheAge() > mSettings.getTimeCacheMaxAge()) {
@@ -605,6 +674,7 @@
// TODO: consider marking "untrusted" times in historical stats
final long currentTime = mTime.hasCache() ? mTime.currentTimeMillis()
: System.currentTimeMillis();
+ final long persistThreshold = mSettings.getPersistThreshold();
final NetworkStats networkSnapshot;
final NetworkStats uidSnapshot;
@@ -620,30 +690,32 @@
}
performNetworkPollLocked(networkSnapshot, currentTime);
- if (detailedPoll) {
- performUidPollLocked(uidSnapshot, currentTime);
+
+ // persist when enough network data has occurred
+ final NetworkStats persistNetworkDelta = computeStatsDelta(
+ mLastPersistNetworkSnapshot, networkSnapshot, true);
+ if (forcePersist || persistNetworkDelta.getTotalBytes() > persistThreshold) {
+ writeNetworkStatsLocked();
+ mLastPersistNetworkSnapshot = networkSnapshot;
}
- // decide if enough has changed to trigger persist
- final NetworkStats persistDelta = computeStatsDelta(
- mLastPersistNetworkSnapshot, networkSnapshot, true);
- final long persistThreshold = mSettings.getPersistThreshold();
+ if (detailedPoll) {
+ performUidPollLocked(uidSnapshot, currentTime);
- NetworkStats.Entry entry = null;
- for (String iface : persistDelta.getUniqueIfaces()) {
- final int index = persistDelta.findIndex(iface, UID_ALL, SET_DEFAULT, TAG_NONE);
- entry = persistDelta.getValues(index, entry);
- if (forcePersist || entry.rxBytes > persistThreshold
- || entry.txBytes > persistThreshold) {
- writeNetworkStatsLocked();
- if (mUidStatsLoaded) {
- writeUidStatsLocked();
- }
+ // persist when enough network data has occurred
+ final NetworkStats persistUidDelta = computeStatsDelta(
+ mLastPersistUidSnapshot, uidSnapshot, true);
+ if (forcePersist || persistUidDelta.getTotalBytes() > persistThreshold) {
+ writeUidStatsLocked();
mLastPersistNetworkSnapshot = networkSnapshot;
- break;
}
}
+ if (LOGV) {
+ final long duration = SystemClock.elapsedRealtime() - startRealtime;
+ Slog.v(TAG, "performPollLocked() took " + duration + "ms");
+ }
+
// finally, dispatch updated event to any listeners
final Intent updatedIntent = new Intent(ACTION_NETWORK_STATS_UPDATED);
updatedIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
@@ -656,7 +728,7 @@
private void performNetworkPollLocked(NetworkStats networkSnapshot, long currentTime) {
final HashSet<String> unknownIface = Sets.newHashSet();
- final NetworkStats delta = computeStatsDelta(mLastNetworkSnapshot, networkSnapshot, false);
+ final NetworkStats delta = computeStatsDelta(mLastPollNetworkSnapshot, networkSnapshot, false);
final long timeStart = currentTime - delta.getElapsedRealtime();
NetworkStats.Entry entry = null;
@@ -678,7 +750,7 @@
history.removeBucketsBefore(currentTime - maxHistory);
}
- mLastNetworkSnapshot = networkSnapshot;
+ mLastPollNetworkSnapshot = networkSnapshot;
if (LOGD && unknownIface.size() > 0) {
Slog.w(TAG, "unknown interfaces " + unknownIface.toString() + ", ignoring those stats");
@@ -691,9 +763,9 @@
private void performUidPollLocked(NetworkStats uidSnapshot, long currentTime) {
ensureUidStatsLoadedLocked();
- final NetworkStats delta = computeStatsDelta(mLastUidSnapshot, uidSnapshot, false);
+ final NetworkStats delta = computeStatsDelta(mLastPollUidSnapshot, uidSnapshot, false);
final NetworkStats operationsDelta = computeStatsDelta(
- mLastOperationsSnapshot, mOperations, false);
+ mLastPollOperationsSnapshot, mOperations, false);
final long timeStart = currentTime - delta.getElapsedRealtime();
NetworkStats.Entry entry = null;
@@ -731,8 +803,8 @@
}
}
- mLastUidSnapshot = uidSnapshot;
- mLastOperationsSnapshot = mOperations;
+ mLastPollUidSnapshot = uidSnapshot;
+ mLastPollOperationsSnapshot = mOperations;
mOperations = new NetworkStats(0L, 10);
}
@@ -1162,8 +1234,12 @@
/** {@inheritDoc} */
public boolean handleMessage(Message msg) {
switch (msg.what) {
- case MSG_FORCE_UPDATE: {
- forceUpdate();
+ case MSG_PERFORM_POLL: {
+ performPoll(false, false);
+ return true;
+ }
+ case MSG_PERFORM_POLL_DETAILED: {
+ performPoll(true, false);
return true;
}
default: {
@@ -1226,10 +1302,10 @@
}
public long getPollInterval() {
- return getSecureLong(NETSTATS_POLL_INTERVAL, 15 * MINUTE_IN_MILLIS);
+ return getSecureLong(NETSTATS_POLL_INTERVAL, 30 * MINUTE_IN_MILLIS);
}
public long getPersistThreshold() {
- return getSecureLong(NETSTATS_PERSIST_THRESHOLD, 16 * KB_IN_BYTES);
+ return getSecureLong(NETSTATS_PERSIST_THRESHOLD, 512 * KB_IN_BYTES);
}
public long getNetworkBucketDuration() {
return getSecureLong(NETSTATS_NETWORK_BUCKET_DURATION, HOUR_IN_MILLIS);
diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java
index 2f19a46..b8797d18 100644
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -194,7 +194,8 @@
/**
* Whether verification is enabled by default.
*/
- private static final boolean DEFAULT_VERIFY_ENABLE = true;
+ // STOPSHIP: change this to true
+ private static final boolean DEFAULT_VERIFY_ENABLE = false;
/**
* The default maximum time to wait for the verification agent to return in
diff --git a/services/sensorservice/Fusion.cpp b/services/sensorservice/Fusion.cpp
index ff4786b..0ab86c3 100644
--- a/services/sensorservice/Fusion.cpp
+++ b/services/sensorservice/Fusion.cpp
@@ -47,9 +47,46 @@
static const float accSTDEV = 0.05f; // m/s^2 (measured 0.08 / CDD 0.05)
static const float magSTDEV = 0.5f; // uT (measured 0.7 / CDD 0.5)
-static const float FREE_FALL_THRESHOLD = 0.981f;
static const float SYMMETRY_TOLERANCE = 1e-10f;
+/*
+ * Accelerometer updates will not be performed near free fall to avoid
+ * ill-conditioning and div by zeros.
+ * Threshhold: 10% of g, in m/s^2
+ */
+static const float FREE_FALL_THRESHOLD = 0.981f;
+static const float FREE_FALL_THRESHOLD_SQ =
+ FREE_FALL_THRESHOLD*FREE_FALL_THRESHOLD;
+
+/*
+ * The geomagnetic-field should be between 30uT and 60uT.
+ * Fields strengths greater than this likely indicate a local magnetic
+ * disturbance which we do not want to update into the fused frame.
+ */
+static const float MAX_VALID_MAGNETIC_FIELD = 100; // uT
+static const float MAX_VALID_MAGNETIC_FIELD_SQ =
+ MAX_VALID_MAGNETIC_FIELD*MAX_VALID_MAGNETIC_FIELD;
+
+/*
+ * Values of the field smaller than this should be ignored in fusion to avoid
+ * ill-conditioning. This state can happen with anomalous local magnetic
+ * disturbances canceling the Earth field.
+ */
+static const float MIN_VALID_MAGNETIC_FIELD = 10; // uT
+static const float MIN_VALID_MAGNETIC_FIELD_SQ =
+ MIN_VALID_MAGNETIC_FIELD*MIN_VALID_MAGNETIC_FIELD;
+
+/*
+ * If the cross product of two vectors has magnitude squared less than this,
+ * we reject it as invalid due to alignment of the vectors.
+ * This threshold is used to check for the case where the magnetic field sample
+ * is parallel to the gravity field, which can happen in certain places due
+ * to magnetic field disturbances.
+ */
+static const float MIN_VALID_CROSS_PRODUCT_MAG = 1.0e-3;
+static const float MIN_VALID_CROSS_PRODUCT_MAG_SQ =
+ MIN_VALID_CROSS_PRODUCT_MAG*MIN_VALID_CROSS_PRODUCT_MAG;
+
// -----------------------------------------------------------------------
template <typename TYPE, size_t C, size_t R>
@@ -240,8 +277,9 @@
status_t Fusion::handleAcc(const vec3_t& a) {
// ignore acceleration data if we're close to free-fall
- if (length(a) < FREE_FALL_THRESHOLD)
+ if (length_squared(a) < FREE_FALL_THRESHOLD_SQ) {
return BAD_VALUE;
+ }
if (!checkInitComplete(ACC, a))
return BAD_VALUE;
@@ -253,15 +291,34 @@
status_t Fusion::handleMag(const vec3_t& m) {
// the geomagnetic-field should be between 30uT and 60uT
- // reject obviously wrong magnetic-fields
- if (length(m) > 100)
+ // reject if too large to avoid spurious magnetic sources
+ const float magFieldSq = length_squared(m);
+ if (magFieldSq > MAX_VALID_MAGNETIC_FIELD_SQ) {
return BAD_VALUE;
+ } else if (magFieldSq < MIN_VALID_MAGNETIC_FIELD_SQ) {
+ // Also reject if too small since we will get ill-defined (zero mag)
+ // cross-products below
+ return BAD_VALUE;
+ }
if (!checkInitComplete(MAG, m))
return BAD_VALUE;
+ // Orthogonalize the magnetic field to the gravity field, mapping it into
+ // tangent to Earth.
const vec3_t up( getRotationMatrix() * Ba );
const vec3_t east( cross_product(m, up) );
+
+ // If the m and up vectors align, the cross product magnitude will
+ // approach 0.
+ // Reject this case as well to avoid div by zero problems and
+ // ill-conditioning below.
+ if (length_squared(east) < MIN_VALID_CROSS_PRODUCT_MAG_SQ) {
+ return BAD_VALUE;
+ }
+
+ // If we have created an orthogonal magnetic field successfully,
+ // then pass it in as the update.
vec3_t north( cross_product(up, east) );
const float l = 1 / length(north);
diff --git a/services/sensorservice/vec.h b/services/sensorservice/vec.h
index f74ccc5..24f30ff 100644
--- a/services/sensorservice/vec.h
+++ b/services/sensorservice/vec.h
@@ -212,6 +212,15 @@
typename TYPE,
size_t SIZE
>
+TYPE PURE length_squared(const V<TYPE, SIZE>& v) {
+ return dot_product(v, v);
+}
+
+template <
+ template<typename T, size_t S> class V,
+ typename TYPE,
+ size_t SIZE
+>
V<TYPE, SIZE> PURE normalize(const V<TYPE, SIZE>& v) {
return v * (1/length(v));
}
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 8b2485a..f8925b8 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -556,6 +556,7 @@
// need a hardware-protected path to external video sink
usage |= GraphicBuffer::USAGE_PROTECTED;
}
+ usage |= GraphicBuffer::USAGE_HW_COMPOSER;
return usage;
}
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 0080202..6fde361 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -2207,7 +2207,7 @@
return BAD_VALUE;
// make sure none of the layers are protected
- const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
+ const LayerVector& layers(mDrawingState.layersSortedByZ);
const size_t count = layers.size();
for (size_t i=0 ; i<count ; ++i) {
const sp<LayerBase>& layer(layers[i]);
diff --git a/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java
index 6138490..6dd8cd6 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java
@@ -38,6 +38,7 @@
import static android.text.format.DateUtils.WEEK_IN_MILLIS;
import static com.android.server.net.NetworkStatsService.ACTION_NETWORK_STATS_POLL;
import static org.easymock.EasyMock.anyLong;
+import static org.easymock.EasyMock.capture;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.eq;
import static org.easymock.EasyMock.expect;
@@ -49,6 +50,7 @@
import android.app.PendingIntent;
import android.content.Intent;
import android.net.IConnectivityManager;
+import android.net.INetworkManagementEventObserver;
import android.net.LinkProperties;
import android.net.NetworkInfo;
import android.net.NetworkInfo.DetailedState;
@@ -65,10 +67,10 @@
import com.android.server.net.NetworkStatsService;
import com.android.server.net.NetworkStatsService.NetworkStatsSettings;
+import org.easymock.Capture;
import org.easymock.EasyMock;
import java.io.File;
-import java.util.concurrent.Future;
import libcore.io.IoUtils;
@@ -105,6 +107,7 @@
private IConnectivityManager mConnManager;
private NetworkStatsService mService;
+ private INetworkManagementEventObserver mNetworkObserver;
@Override
public void setUp() throws Exception {
@@ -132,13 +135,20 @@
expectDefaultSettings();
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
- final Future<?> firstPoll = expectSystemReady();
+ expectSystemReady();
+
+ // catch INetworkManagementEventObserver during systemReady()
+ final Capture<INetworkManagementEventObserver> networkObserver = new Capture<
+ INetworkManagementEventObserver>();
+ mNetManager.registerObserver(capture(networkObserver));
+ expectLastCall().atLeastOnce();
replay();
mService.systemReady();
- firstPoll.get();
verifyAndReset();
+ mNetworkObserver = networkObserver.getValue();
+
}
@Override
@@ -183,6 +193,7 @@
expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
.addIfaceValues(TEST_IFACE, 1024L, 1L, 2048L, 2L));
expectNetworkStatsUidDetail(buildEmptyStats());
+ expectNetworkStatsPoll();
replay();
mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
@@ -199,6 +210,7 @@
expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
.addIfaceValues(TEST_IFACE, 4096L, 4L, 8192L, 8L));
expectNetworkStatsUidDetail(buildEmptyStats());
+ expectNetworkStatsPoll();
replay();
mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
@@ -238,6 +250,7 @@
.addValues(TEST_IFACE, UID_RED, SET_FOREGROUND, TAG_NONE, 512L, 4L, 256L, 2L, 0L)
.addValues(TEST_IFACE, UID_RED, SET_FOREGROUND, 0xFAAD, 256L, 2L, 128L, 1L, 0L)
.addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 128L, 1L, 128L, 1L, 0L));
+ expectNetworkStatsPoll();
mService.setUidForeground(UID_RED, false);
mService.incrementOperationCount(UID_RED, 0xFAAD, 4);
@@ -273,11 +286,18 @@
expectDefaultSettings();
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
- final Future<?> firstPoll = expectSystemReady();
+ expectSystemReady();
+
+ // catch INetworkManagementEventObserver during systemReady()
+ final Capture<INetworkManagementEventObserver> networkObserver = new Capture<
+ INetworkManagementEventObserver>();
+ mNetManager.registerObserver(capture(networkObserver));
+ expectLastCall().atLeastOnce();
replay();
mService.systemReady();
- firstPoll.get();
+
+ mNetworkObserver = networkObserver.getValue();
// after systemReady(), we should have historical stats loaded again
assertNetworkTotal(sTemplateWifi, 1024L, 8L, 2048L, 16L, 0);
@@ -312,6 +332,7 @@
expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
.addIfaceValues(TEST_IFACE, 512L, 4L, 512L, 4L));
expectNetworkStatsUidDetail(buildEmptyStats());
+ expectNetworkStatsPoll();
replay();
mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
@@ -329,6 +350,7 @@
expectSettings(0L, 30 * MINUTE_IN_MILLIS, WEEK_IN_MILLIS);
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
+ expectNetworkStatsPoll();
replay();
mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
@@ -363,6 +385,7 @@
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1536L, 12L, 512L, 4L, 0L)
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L)
.addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 512L, 4L, 0L, 0L, 0L));
+ expectNetworkStatsPoll();
mService.incrementOperationCount(UID_RED, 0xF00D, 10);
@@ -384,6 +407,7 @@
expectNetworkState(buildMobile3gState(IMSI_2));
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
+ expectNetworkStatsPoll();
replay();
mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION));
@@ -399,6 +423,7 @@
expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
.addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 128L, 1L, 1024L, 8L, 0L)
.addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, 0xFAAD, 128L, 1L, 1024L, 8L, 0L));
+ expectNetworkStatsPoll();
mService.incrementOperationCount(UID_BLUE, 0xFAAD, 10);
@@ -441,6 +466,7 @@
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xFAAD, 16L, 1L, 16L, 1L, 0L)
.addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 4096L, 258L, 512L, 32L, 0L)
.addValues(TEST_IFACE, UID_GREEN, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L));
+ expectNetworkStatsPoll();
mService.incrementOperationCount(UID_RED, 0xFAAD, 10);
@@ -494,6 +520,7 @@
expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 0L)
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L));
+ expectNetworkStatsPoll();
mService.incrementOperationCount(UID_RED, 0xF00D, 5);
@@ -511,6 +538,7 @@
expectNetworkState(buildMobile4gState());
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
+ expectNetworkStatsPoll();
replay();
mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION));
@@ -525,6 +553,7 @@
expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 512L, 4L, 256L, 2L, 0L)
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xFAAD, 512L, 4L, 256L, 2L, 0L));
+ expectNetworkStatsPoll();
mService.incrementOperationCount(UID_RED, 0xFAAD, 5);
@@ -558,6 +587,7 @@
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 50L, 5L, 50L, 5L, 0L)
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 10L, 1L, 10L, 1L, 0L)
.addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 1024L, 8L, 512L, 4L, 0L));
+ expectNetworkStatsPoll();
mService.incrementOperationCount(UID_RED, 0xF00D, 1);
@@ -576,6 +606,7 @@
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
.addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 2048L, 16L, 1024L, 8L, 0L));
+ expectNetworkStatsPoll();
replay();
mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
@@ -617,6 +648,7 @@
expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 0L)
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 64L, 1L, 64L, 1L, 0L));
+ expectNetworkStatsPoll();
mService.incrementOperationCount(UID_RED, 0xF00D, 1);
@@ -637,6 +669,7 @@
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 64L, 1L, 64L, 1L, 0L)
.addValues(TEST_IFACE, UID_RED, SET_FOREGROUND, TAG_NONE, 32L, 2L, 32L, 2L, 0L)
.addValues(TEST_IFACE, UID_RED, SET_FOREGROUND, 0xFAAD, 1L, 1L, 1L, 1L, 0L));
+ expectNetworkStatsPoll();
mService.setUidForeground(UID_RED, true);
mService.incrementOperationCount(UID_RED, 0xFAAD, 1);
@@ -679,7 +712,7 @@
txPackets, operations);
}
- private Future<?> expectSystemReady() throws Exception {
+ private void expectSystemReady() throws Exception {
mAlarmManager.remove(isA(PendingIntent.class));
expectLastCall().anyTimes();
@@ -687,8 +720,8 @@
eq(AlarmManager.ELAPSED_REALTIME), anyLong(), anyLong(), isA(PendingIntent.class));
expectLastCall().atLeastOnce();
- return mServiceContext.nextBroadcastIntent(
- NetworkStatsService.ACTION_NETWORK_STATS_UPDATED);
+ mNetManager.setGlobalAlert(anyLong());
+ expectLastCall().atLeastOnce();
}
private void expectNetworkState(NetworkState... state) throws Exception {
@@ -727,6 +760,11 @@
expect(mTime.getCacheCertainty()).andReturn(0L).anyTimes();
}
+ private void expectNetworkStatsPoll() throws Exception {
+ mNetManager.setGlobalAlert(anyLong());
+ expectLastCall().anyTimes();
+ }
+
private void assertStatsFilesExist(boolean exist) {
final File networkFile = new File(mStatsDir, "netstats.bin");
final File uidFile = new File(mStatsDir, "netstats_uid.bin");
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/GLTextureViewActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/GLTextureViewActivity.java
index e77178d..3232eedc 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/GLTextureViewActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/GLTextureViewActivity.java
@@ -33,7 +33,6 @@
import android.widget.FrameLayout;
import javax.microedition.khronos.egl.EGL10;
-import javax.microedition.khronos.egl.EGL11;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.egl.EGLContext;
import javax.microedition.khronos.egl.EGLDisplay;
@@ -207,7 +206,7 @@
glEnableVertexAttribArray(attribTexCoords);
checkGlError();
- glUniform1i(texture, 0);
+ glUniform1i(uniformTexture, texture);
checkGlError();
while (!mFinished) {
@@ -350,7 +349,7 @@
!mEglSurface.equals(mEgl.eglGetCurrentSurface(EGL10.EGL_DRAW))) {
if (!mEgl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)) {
throw new RuntimeException("eglMakeCurrent failed "
- + getEGLErrorString(mEgl.eglGetError()));
+ + GLUtils.getEGLErrorString(mEgl.eglGetError()));
}
}
}
@@ -361,13 +360,13 @@
mEglDisplay = mEgl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
if (mEglDisplay == EGL10.EGL_NO_DISPLAY) {
throw new RuntimeException("eglGetDisplay failed "
- + getEGLErrorString(mEgl.eglGetError()));
+ + GLUtils.getEGLErrorString(mEgl.eglGetError()));
}
int[] version = new int[2];
if (!mEgl.eglInitialize(mEglDisplay, version)) {
throw new RuntimeException("eglInitialize failed " +
- getEGLErrorString(mEgl.eglGetError()));
+ GLUtils.getEGLErrorString(mEgl.eglGetError()));
}
mEglConfig = chooseEglConfig();
@@ -386,12 +385,12 @@
return;
}
throw new RuntimeException("createWindowSurface failed "
- + getEGLErrorString(error));
+ + GLUtils.getEGLErrorString(error));
}
if (!mEgl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)) {
throw new RuntimeException("eglMakeCurrent failed "
- + getEGLErrorString(mEgl.eglGetError()));
+ + GLUtils.getEGLErrorString(mEgl.eglGetError()));
}
mGL = mEglContext.getGL();
@@ -409,7 +408,7 @@
int[] configSpec = getConfig();
if (!mEgl.eglChooseConfig(mEglDisplay, configSpec, configs, 1, configsCount)) {
throw new IllegalArgumentException("eglChooseConfig failed " +
- getEGLErrorString(mEgl.eglGetError()));
+ GLUtils.getEGLErrorString(mEgl.eglGetError()));
} else if (configsCount[0] > 0) {
return configs[0];
}
@@ -429,43 +428,6 @@
};
}
- static String getEGLErrorString(int error) {
- switch (error) {
- case EGL10.EGL_SUCCESS:
- return "EGL_SUCCESS";
- case EGL10.EGL_NOT_INITIALIZED:
- return "EGL_NOT_INITIALIZED";
- case EGL10.EGL_BAD_ACCESS:
- return "EGL_BAD_ACCESS";
- case EGL10.EGL_BAD_ALLOC:
- return "EGL_BAD_ALLOC";
- case EGL10.EGL_BAD_ATTRIBUTE:
- return "EGL_BAD_ATTRIBUTE";
- case EGL10.EGL_BAD_CONFIG:
- return "EGL_BAD_CONFIG";
- case EGL10.EGL_BAD_CONTEXT:
- return "EGL_BAD_CONTEXT";
- case EGL10.EGL_BAD_CURRENT_SURFACE:
- return "EGL_BAD_CURRENT_SURFACE";
- case EGL10.EGL_BAD_DISPLAY:
- return "EGL_BAD_DISPLAY";
- case EGL10.EGL_BAD_MATCH:
- return "EGL_BAD_MATCH";
- case EGL10.EGL_BAD_NATIVE_PIXMAP:
- return "EGL_BAD_NATIVE_PIXMAP";
- case EGL10.EGL_BAD_NATIVE_WINDOW:
- return "EGL_BAD_NATIVE_WINDOW";
- case EGL10.EGL_BAD_PARAMETER:
- return "EGL_BAD_PARAMETER";
- case EGL10.EGL_BAD_SURFACE:
- return "EGL_BAD_SURFACE";
- case EGL11.EGL_CONTEXT_LOST:
- return "EGL_CONTEXT_LOST";
- default:
- return "0x" + Integer.toHexString(error);
- }
- }
-
void finish() {
mFinished = true;
}