Merge "Prevent dup network adding - b/5200491"
diff --git a/api/current.txt b/api/current.txt
index 250f09f..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
@@ -11690,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);
@@ -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";
   }
@@ -16685,6 +16686,7 @@
     field public static final java.lang.String ACCOUNT_NAME = "account_name";
     field public static final java.lang.String ACCOUNT_TYPE = "account_type";
     field public static final java.lang.String COMMENTS = "comments";
+    field public static final java.lang.String CONTACT_ID = "contact_id";
     field public static final java.lang.String DATA_SET = "data_set";
     field public static final java.lang.String RAW_CONTACT_ID = "raw_contact_id";
     field public static final java.lang.String RAW_CONTACT_SOURCE_ID = "raw_contact_source_id";
@@ -17144,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";
@@ -20811,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";
@@ -27131,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/stagefright/stream.cpp b/cmds/stagefright/stream.cpp
index ee91c29..aa3bc03 100644
--- a/cmds/stagefright/stream.cpp
+++ b/cmds/stagefright/stream.cpp
@@ -14,6 +14,10 @@
  * limitations under the License.
  */
 
+//#define LOG_NDEBUG 0
+#define LOG_TAG "stream"
+#include "utils/Log.h"
+
 #include <binder/ProcessState.h>
 
 #include <media/IStreamSource.h>
@@ -50,7 +54,7 @@
 private:
     int mFd;
     off64_t mFileSize;
-    int64_t mNextSeekTimeUs;
+    uint64_t mNumPacketsSent;
 
     sp<IStreamListener> mListener;
     Vector<sp<IMemory> > mBuffers;
@@ -61,7 +65,7 @@
 MyStreamSource::MyStreamSource(int fd)
     : mFd(fd),
       mFileSize(0),
-      mNextSeekTimeUs(-1) {  // ALooper::GetNowUs() + 5000000ll) {
+      mNumPacketsSent(0) {
     CHECK_GE(fd, 0);
 
     mFileSize = lseek64(fd, 0, SEEK_END);
@@ -84,18 +88,24 @@
 void MyStreamSource::onBufferAvailable(size_t index) {
     CHECK_LT(index, mBuffers.size());
 
-    if (mNextSeekTimeUs >= 0 && mNextSeekTimeUs <= ALooper::GetNowUs()) {
-        off64_t offset = (off64_t)(((float)rand() / RAND_MAX) * mFileSize * 0.8);
-        offset = (offset / 188) * 188;
+#if 0
+    if (mNumPacketsSent >= 20000) {
+        LOGI("signalling discontinuity now");
+
+        off64_t offset = 0;
+        CHECK((offset % 188) == 0);
 
         lseek(mFd, offset, SEEK_SET);
 
-        mListener->issueCommand(
-                IStreamListener::DISCONTINUITY, false /* synchronous */);
+        sp<AMessage> extra = new AMessage;
+        extra->setInt32(IStreamListener::kKeyFormatChange, 0);
 
-        mNextSeekTimeUs = -1;
-        mNextSeekTimeUs = ALooper::GetNowUs() + 5000000ll;
+        mListener->issueCommand(
+                IStreamListener::DISCONTINUITY, false /* synchronous */, extra);
+
+        mNumPacketsSent = 0;
     }
+#endif
 
     sp<IMemory> mem = mBuffers.itemAt(index);
 
@@ -104,6 +114,8 @@
         mListener->issueCommand(IStreamListener::EOS, false /* synchronous */);
     } else {
         mListener->queueBuffer(index, n);
+
+        mNumPacketsSent += n / 188;
     }
 }
 ////////////////////////////////////////////////////////////////////////////////
@@ -293,12 +305,17 @@
     sp<SurfaceComposerClient> composerClient = new SurfaceComposerClient;
     CHECK_EQ(composerClient->initCheck(), (status_t)OK);
 
+    ssize_t displayWidth = composerClient->getDisplayWidth(0);
+    ssize_t displayHeight = composerClient->getDisplayHeight(0);
+
+    LOGV("display is %d x %d\n", displayWidth, displayHeight);
+
     sp<SurfaceControl> control =
         composerClient->createSurface(
                 String8("A Surface"),
                 0,
-                1280,
-                800,
+                displayWidth,
+                displayHeight,
                 PIXEL_FORMAT_RGB_565,
                 0);
 
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/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 a66fa81..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);
@@ -3059,6 +3060,12 @@
      */
     protected interface StreamItemsColumns {
         /**
+         * A reference to the {@link android.provider.ContactsContract.Contacts#_ID}
+         * that this stream item belongs to.
+         */
+        public static final String CONTACT_ID = "contact_id";
+
+        /**
          * A reference to the {@link RawContacts#_ID}
          * that this stream item belongs to.
          */
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/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java
index cfbb47c..c934c7b 100644
--- a/core/java/android/view/GLES20Canvas.java
+++ b/core/java/android/view/GLES20Canvas.java
@@ -541,9 +541,19 @@
     
     @Override
     public int saveLayer(RectF bounds, Paint paint, int saveFlags) {
-        return saveLayer(bounds.left, bounds.top, bounds.right, bounds.bottom, paint, saveFlags);
+        if (bounds != null) {
+            return saveLayer(bounds.left, bounds.top, bounds.right, bounds.bottom, paint, saveFlags);
+        }
+
+        int modifier = paint != null ? setupColorFilter(paint) : MODIFIER_NONE;
+        final int nativePaint = paint == null ? 0 : paint.mNativePaint;
+        int count = nSaveLayer(mRenderer, nativePaint, saveFlags);
+        if (modifier != MODIFIER_NONE) nResetModifiers(mRenderer, modifier);
+        return count;
     }
 
+    private static native int nSaveLayer(int renderer, int paint, int saveFlags);    
+
     @Override
     public int saveLayer(float left, float top, float right, float bottom, Paint paint,
             int saveFlags) {
@@ -562,10 +572,15 @@
 
     @Override
     public int saveLayerAlpha(RectF bounds, int alpha, int saveFlags) {
-        return saveLayerAlpha(bounds.left, bounds.top, bounds.right, bounds.bottom,
-                alpha, saveFlags);
+        if (bounds != null) {
+            return saveLayerAlpha(bounds.left, bounds.top, bounds.right, bounds.bottom,
+                    alpha, saveFlags);
+        }
+        return nSaveLayerAlpha(mRenderer, alpha, saveFlags);
     }
 
+    private static native int nSaveLayerAlpha(int renderer, int alpha, int saveFlags);    
+
     @Override
     public int saveLayerAlpha(float left, float top, float right, float bottom, int alpha,
             int saveFlags) {
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 17e637c..80b5dad 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);
 
@@ -9992,8 +9992,6 @@
                 // The dirty rect should always be null for a display list
                 canvas.onPreDraw(null);
 
-                final int restoreCount = canvas.save();
-
                 computeScroll();
                 canvas.translate(-mScrollX, -mScrollY);
                 mPrivateFlags |= DRAWN | DRAWING_CACHE_VALID;
@@ -10005,8 +10003,6 @@
                 } else {
                     draw(canvas);
                 }
-
-                canvas.restoreToCount(restoreCount);
             } finally {
                 canvas.onPostDraw();
 
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/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/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 5d776fd..8c3c212 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -3451,6 +3451,7 @@
                 }
                 abortAnimation();
                 mPrivateHandler.removeMessages(RESUME_WEBCORE_PRIORITY);
+                nativeSetIsScrolling(false);
                 if (!mBlockWebkitViewMessages) {
                     WebViewCore.resumePriority();
                     if (!mSelectingText) {
@@ -6382,6 +6383,8 @@
         WebViewCore.reducePriority();
         // to get better performance, pause updating the picture
         WebViewCore.pauseUpdatePicture(mWebViewCore);
+        nativeSetIsScrolling(true);
+
         if (!mDragFromTextInput) {
             nativeHideCursor();
         }
@@ -6478,6 +6481,7 @@
                 || mTouchMode == TOUCH_DRAG_LAYER_MODE) && !mSelectingText) {
             WebViewCore.resumePriority();
             WebViewCore.resumeUpdatePicture(mWebViewCore);
+            nativeSetIsScrolling(false);
         }
         mPrivateHandler.removeMessages(SWITCH_TO_SHORTPRESS);
         mPrivateHandler.removeMessages(SWITCH_TO_LONGPRESS);
@@ -9277,6 +9281,7 @@
      * @return True if the layer is successfully scrolled.
      */
     private native boolean  nativeScrollLayer(int layer, int newX, int newY);
+    private native void     nativeSetIsScrolling(boolean isScrolling);
     private native int      nativeGetBackgroundColor();
     native boolean  nativeSetProperty(String key, String value);
     native String   nativeGetProperty(String key);
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index 400cdbd..fe07a76 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -2070,10 +2070,8 @@
             if (!core.getSettings().enableSmoothTransition()) return;
 
             synchronized (core) {
+                core.nativeSetIsPaused(true);
                 core.mDrawIsPaused = true;
-                if (core.mDrawIsScheduled) {
-                    core.mEventHub.removeMessages(EventHub.WEBKIT_DRAW);
-                }
             }
         }
 
@@ -2082,15 +2080,14 @@
     static void resumeUpdatePicture(WebViewCore core) {
         if (core != null) {
             // if mDrawIsPaused is true, ignore the setting, continue to resume
-            if (!core.mDrawIsPaused
-                    && !core.getSettings().enableSmoothTransition()) return;
+            if (!core.mDrawIsPaused)
+                return;
 
             synchronized (core) {
+                core.nativeSetIsPaused(false);
                 core.mDrawIsPaused = false;
                 // always redraw on resume to reenable gif animations
                 core.mDrawIsScheduled = false;
-                core.nativeContentInvalidateAll();
-                core.contentDraw();
             }
         }
     }
@@ -2127,7 +2124,6 @@
             // only fire an event if this is our first request
             if (mDrawIsScheduled) return;
             mDrawIsScheduled = true;
-            if (mDrawIsPaused) return;
             mEventHub.sendMessage(Message.obtain(null, EventHub.WEBKIT_DRAW));
         }
     }
@@ -2789,6 +2785,7 @@
         return mDeviceOrientationService;
     }
 
+    private native void nativeSetIsPaused(boolean isPaused);
     private native void nativePause();
     private native void nativeResume();
     private native void nativeFreeMemory();
diff --git a/core/java/android/widget/FastScroller.java b/core/java/android/widget/FastScroller.java
index 7ad5d6c..51506e8 100644
--- a/core/java/android/widget/FastScroller.java
+++ b/core/java/android/widget/FastScroller.java
@@ -368,8 +368,10 @@
         } else if (mState == STATE_EXIT) {
             if (alpha == 0) { // Done with exit
                 setState(STATE_NONE);
+            } else if (mTrackDrawable != null) {
+                mList.invalidate(viewWidth - mThumbW, 0, viewWidth, mList.getHeight());
             } else {
-                mList.invalidate(viewWidth - mThumbW, y, viewWidth, y + mThumbH);            
+                mList.invalidate(viewWidth - mThumbW, y, viewWidth, y + mThumbH);
             }
         }
     }
@@ -597,7 +599,7 @@
 
     private int getThumbPositionForListPosition(int firstVisibleItem, int visibleItemCount,
             int totalItemCount) {
-        if (mSectionIndexer == null) {
+        if (mSectionIndexer == null || mListAdapter == null) {
             getSectionsFromIndexer();
         }
         if (mSectionIndexer == null || !mMatchDragPosition) {
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..c92b5f9 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);
         }
@@ -4791,8 +4788,7 @@
             selEnd = getSelectionEnd();
 
             if (selStart >= 0) {
-                if (mHighlightPath == null)
-                    mHighlightPath = new Path();
+                if (mHighlightPath == null) mHighlightPath = new Path();
 
                 if (selStart == selEnd) {
                     if (isCursorVisible() &&
@@ -4998,6 +4994,7 @@
             } else {
                 // Selection extends across multiple lines -- the focused
                 // rect covers the entire width.
+                if (mHighlightPath == null) mHighlightPath = new Path();
                 if (mHighlightPathBogus) {
                     mHighlightPath.reset();
                     mLayout.getSelectionPath(selStart, selEnd, mHighlightPath);
@@ -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,96 @@
                 }
             }
         }
+
+        if (what instanceof SpellCheckSpan) {
+            if (newStart < 0) {
+                getSpellChecker().removeSpellCheckSpan((SpellCheckSpan) what);
+            } else if (oldStart < 0) {
+                getSpellChecker().addSpellCheckSpan((SpellCheckSpan) what);
+            }
+        }
     }
 
-    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 +7740,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 +7750,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 +7948,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 +8079,8 @@
                         }
                     }
                 }
+
+                handled = true;
             }
 
             if (handled) {
@@ -7980,11 +8092,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 +8568,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 +8583,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 +8925,7 @@
             final int offset = getOffsetForPosition(mLastDownPositionX, mLastDownPositionY);
             stopSelectionActionMode();
             Selection.setSelection((Spannable) mText, offset);
-            getInsertionController().showImmediately();
+            getInsertionController().showWithActionPopup();
             handled = true;
         }
 
@@ -9067,10 +9202,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 +9286,10 @@
         @Override
         public void show() {
             if (!(mText instanceof Editable)) return;
-            updateSuggestions();
 
-            super.show();
+            if (updateSuggestions()) {
+                super.show();
+            }
         }
 
         @Override
@@ -9179,7 +9317,7 @@
             }
         }
 
-        private void updateSuggestions() {
+        private boolean updateSuggestions() {
             Spannable spannable = (Spannable)TextView.this.mText;
             SuggestionSpan[] suggestionSpans = getSuggestionSpans();
 
@@ -9217,22 +9355,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 +9372,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 +9574,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 +9632,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 +9941,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 +9956,9 @@
                 onTextContextMenuItem(ID_PASTE);
                 hide();
             } else if (view == mReplaceTextView) {
+                final int middle = (getSelectionStart() + getSelectionEnd()) / 2;
+                stopSelectionActionMode();
+                Selection.setSelection((Spannable) mText, middle);
                 showSuggestions();
             }
         }
@@ -10133,17 +10290,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 +10352,7 @@
                                 // Tapping on the handle dismisses the displayed action popup
                                 mActionPopupWindow.hide();
                             } else {
-                                show(0);
+                                showWithActionPopup();
                             }
                         }
                     }
@@ -10349,16 +10507,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 +10546,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 +11035,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/widget/ActionBarView.java b/core/java/com/android/internal/widget/ActionBarView.java
index 4efb29f..8988c9f 100644
--- a/core/java/com/android/internal/widget/ActionBarView.java
+++ b/core/java/com/android/internal/widget/ActionBarView.java
@@ -826,15 +826,18 @@
             rightOfCenter = Math.max(0, rightOfCenter - mMenuView.getMeasuredWidth());
         }
 
-        if (mExpandedActionView == null) {
-            boolean showTitle = mTitleLayout != null && mTitleLayout.getVisibility() != GONE &&
-                    (mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0;
-            if (showTitle) {
-                availableWidth = measureChildView(mTitleLayout, availableWidth,
-                        MeasureSpec.makeMeasureSpec(mContentHeight, MeasureSpec.EXACTLY), 0);
-                leftOfCenter = Math.max(0, leftOfCenter - mTitleLayout.getMeasuredWidth());
-            }
+        if (mIndeterminateProgressView != null &&
+                mIndeterminateProgressView.getVisibility() != GONE) {
+            availableWidth = measureChildView(mIndeterminateProgressView, availableWidth,
+                    childSpecHeight, 0);
+            rightOfCenter = Math.max(0,
+                    rightOfCenter - mIndeterminateProgressView.getMeasuredWidth());
+        }
 
+        final boolean showTitle = mTitleLayout != null && mTitleLayout.getVisibility() != GONE &&
+                (mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0;
+
+        if (mExpandedActionView == null) {
             switch (mNavigationMode) {
                 case ActionBar.NAVIGATION_MODE_LIST:
                     if (mListNavLayout != null) {
@@ -865,14 +868,6 @@
             }
         }
 
-        if (mIndeterminateProgressView != null &&
-                mIndeterminateProgressView.getVisibility() != GONE) {
-            availableWidth = measureChildView(mIndeterminateProgressView, availableWidth,
-                    childSpecHeight, 0);
-            rightOfCenter = Math.max(0,
-                    rightOfCenter - mIndeterminateProgressView.getMeasuredWidth());
-        }
-
         View customView = null;
         if (mExpandedActionView != null) {
             customView = mExpandedActionView;
@@ -922,6 +917,13 @@
             customView.measure(
                     MeasureSpec.makeMeasureSpec(customNavWidth, customNavWidthMode),
                     MeasureSpec.makeMeasureSpec(customNavHeight, customNavHeightMode));
+            availableWidth -= horizontalMargin + customView.getMeasuredWidth();
+        }
+
+        if (mExpandedActionView == null && showTitle) {
+            availableWidth = measureChildView(mTitleLayout, availableWidth,
+                    MeasureSpec.makeMeasureSpec(mContentHeight, MeasureSpec.EXACTLY), 0);
+            leftOfCenter = Math.max(0, leftOfCenter - mTitleLayout.getMeasuredWidth());
         }
 
         if (mContentHeight <= 0) {
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/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index fb5e5fe..bcf8e71 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -222,12 +222,26 @@
     return renderer->saveLayer(left, top, right, bottom, paint, saveFlags);
 }
 
+static jint android_view_GLES20Canvas_saveLayerClip(JNIEnv* env, jobject clazz,
+        OpenGLRenderer* renderer, SkPaint* paint, jint saveFlags) {
+    const android::uirenderer::Rect& bounds(renderer->getClipBounds());
+    return renderer->saveLayer(bounds.left, bounds.top, bounds.right, bounds.bottom,
+            paint, saveFlags);
+}
+
 static jint android_view_GLES20Canvas_saveLayerAlpha(JNIEnv* env, jobject clazz,
         OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom,
         jint alpha, jint saveFlags) {
     return renderer->saveLayerAlpha(left, top, right, bottom, alpha, saveFlags);
 }
 
+static jint android_view_GLES20Canvas_saveLayerAlphaClip(JNIEnv* env, jobject clazz,
+        OpenGLRenderer* renderer, jint alpha, jint saveFlags) {
+    const android::uirenderer::Rect& bounds(renderer->getClipBounds());
+    return renderer->saveLayerAlpha(bounds.left, bounds.top, bounds.right, bounds.bottom,
+            alpha, saveFlags);
+}
+
 // ----------------------------------------------------------------------------
 // Clipping
 // ----------------------------------------------------------------------------
@@ -759,7 +773,9 @@
     { "nGetSaveCount",      "(I)I",            (void*) android_view_GLES20Canvas_getSaveCount },
 
     { "nSaveLayer",         "(IFFFFII)I",      (void*) android_view_GLES20Canvas_saveLayer },
+    { "nSaveLayer",         "(III)I",          (void*) android_view_GLES20Canvas_saveLayerClip },
     { "nSaveLayerAlpha",    "(IFFFFII)I",      (void*) android_view_GLES20Canvas_saveLayerAlpha },
+    { "nSaveLayerAlpha",    "(III)I",          (void*) android_view_GLES20Canvas_saveLayerAlphaClip },
 
     { "nQuickReject",       "(IFFFFI)Z",       (void*) android_view_GLES20Canvas_quickReject },
     { "nClipRect",          "(IFFFFI)Z",       (void*) android_view_GLES20Canvas_clipRectF },
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/quickcontact_badge_overlay_normal_dark.9.png b/core/res/res/drawable-hdpi/quickcontact_badge_overlay_normal_dark.9.png
index da28a17..db23635 100644
--- a/core/res/res/drawable-hdpi/quickcontact_badge_overlay_normal_dark.9.png
+++ b/core/res/res/drawable-hdpi/quickcontact_badge_overlay_normal_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/quickcontact_badge_overlay_normal_light.9.png b/core/res/res/drawable-hdpi/quickcontact_badge_overlay_normal_light.9.png
index 015d30a..269a456 100644
--- a/core/res/res/drawable-hdpi/quickcontact_badge_overlay_normal_light.9.png
+++ b/core/res/res/drawable-hdpi/quickcontact_badge_overlay_normal_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/quickcontact_badge_overlay_pressed_dark.9.png b/core/res/res/drawable-hdpi/quickcontact_badge_overlay_pressed_dark.9.png
index df7f236..d997b36 100644
--- a/core/res/res/drawable-hdpi/quickcontact_badge_overlay_pressed_dark.9.png
+++ b/core/res/res/drawable-hdpi/quickcontact_badge_overlay_pressed_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/quickcontact_badge_overlay_pressed_light.9.png b/core/res/res/drawable-hdpi/quickcontact_badge_overlay_pressed_light.9.png
index 8950f81..8ed5eb7 100644
--- a/core/res/res/drawable-hdpi/quickcontact_badge_overlay_pressed_light.9.png
+++ b/core/res/res/drawable-hdpi/quickcontact_badge_overlay_pressed_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_16_inner_holo.png b/core/res/res/drawable-hdpi/spinner_16_inner_holo.png
index 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/quickcontact_badge_overlay_normal_dark.9.png b/core/res/res/drawable-mdpi/quickcontact_badge_overlay_normal_dark.9.png
index 0fc20e0..84d4c11 100644
--- a/core/res/res/drawable-mdpi/quickcontact_badge_overlay_normal_dark.9.png
+++ b/core/res/res/drawable-mdpi/quickcontact_badge_overlay_normal_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/quickcontact_badge_overlay_normal_light.9.png b/core/res/res/drawable-mdpi/quickcontact_badge_overlay_normal_light.9.png
index 2b7a262..d922ef1 100644
--- a/core/res/res/drawable-mdpi/quickcontact_badge_overlay_normal_light.9.png
+++ b/core/res/res/drawable-mdpi/quickcontact_badge_overlay_normal_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/quickcontact_badge_overlay_pressed_dark.9.png b/core/res/res/drawable-mdpi/quickcontact_badge_overlay_pressed_dark.9.png
index 1410805..8c37c8d 100644
--- a/core/res/res/drawable-mdpi/quickcontact_badge_overlay_pressed_dark.9.png
+++ b/core/res/res/drawable-mdpi/quickcontact_badge_overlay_pressed_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/quickcontact_badge_overlay_pressed_light.9.png b/core/res/res/drawable-mdpi/quickcontact_badge_overlay_pressed_light.9.png
index 34d79f6..e442c28 100644
--- a/core/res/res/drawable-mdpi/quickcontact_badge_overlay_pressed_light.9.png
+++ b/core/res/res/drawable-mdpi/quickcontact_badge_overlay_pressed_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_16_inner_holo.png b/core/res/res/drawable-mdpi/spinner_16_inner_holo.png
index 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/quickcontact_badge_overlay_normal_dark.9.png b/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_normal_dark.9.png
index 3c8979f..9cf9173 100644
--- a/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_normal_dark.9.png
+++ b/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_normal_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_normal_light.9.png b/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_normal_light.9.png
index 45b7adb..c8d8a17 100644
--- a/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_normal_light.9.png
+++ b/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_normal_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_pressed_dark.9.png b/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_pressed_dark.9.png
index e258284a..e3793f7 100644
--- a/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_pressed_dark.9.png
+++ b/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_pressed_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_pressed_light.9.png b/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_pressed_light.9.png
index 5c4bbf5..c0be34f0 100644
--- a/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_pressed_light.9.png
+++ b/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_pressed_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/spinner_16_inner_holo.png b/core/res/res/drawable-xhdpi/spinner_16_inner_holo.png
index 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-sw600dp/preference_list_content.xml b/core/res/res/layout-sw600dp/preference_list_content.xml
deleted file mode 100644
index 08f6453..0000000
--- a/core/res/res/layout-sw600dp/preference_list_content.xml
+++ /dev/null
@@ -1,123 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* //device/apps/common/assets/res/layout/list_content.xml
-**
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:orientation="vertical"
-    android:layout_height="match_parent"
-    android:layout_width="match_parent">
-
-    <LinearLayout
-        android:orientation="horizontal"
-        android:layout_width="match_parent"
-        android:layout_height="0px"
-        android:layout_marginTop="@dimen/preference_screen_top_margin"
-        android:layout_marginBottom="@dimen/preference_screen_bottom_margin"
-        android:layout_weight="1">
-
-        <LinearLayout
-            android:id="@+id/headers"
-            android:orientation="vertical"
-            android:layout_width="0px"
-            android:layout_height="match_parent"
-            android:layout_marginRight="@dimen/preference_screen_side_margin_negative"
-            android:layout_marginLeft="@dimen/preference_screen_side_margin"
-            android:layout_weight="@integer/preferences_left_pane_weight">
-
-            <ListView android:id="@android:id/list"
-                android:layout_width="match_parent"
-                android:layout_height="0px"
-                android:layout_weight="1"
-                android:paddingLeft="@dimen/preference_screen_header_padding_side"
-                android:paddingRight="@dimen/preference_screen_header_padding_side"
-                android:paddingTop="@dimen/preference_screen_header_vertical_padding"
-                android:paddingBottom="@dimen/preference_screen_header_vertical_padding"
-                android:scrollbarStyle="@integer/preference_screen_header_scrollbarStyle"
-                android:drawSelectorOnTop="false"
-                android:cacheColorHint="@android:color/transparent"
-                android:listPreferredItemHeight="48dp"
-                android:scrollbarAlwaysDrawVerticalTrack="true" />
-
-            <FrameLayout android:id="@+id/list_footer"
-                    android:layout_width="match_parent"
-                    android:layout_height="wrap_content"
-                    android:layout_weight="0" />
-
-        </LinearLayout>
-
-        <LinearLayout
-                android:id="@+id/prefs_frame"
-                android:layout_width="0px"
-                android:layout_height="match_parent"
-                android:layout_weight="@integer/preferences_right_pane_weight"
-                android:layout_marginLeft="@dimen/preference_screen_side_margin"
-                android:layout_marginRight="@dimen/preference_screen_side_margin"
-                android:background="?attr/detailsElementBackground"
-                android:orientation="vertical"
-                android:visibility="gone" >
-
-            <!-- Breadcrumb inserted here, in certain screen sizes. In others, it will be an
-                empty layout or just padding, and PreferenceActivity will put the breadcrumbs in
-                the action bar. -->
-            <include layout="@layout/breadcrumbs_in_fragment" />
-
-            <android.preference.PreferenceFrameLayout android:id="@+id/prefs"
-                    android:layout_width="match_parent"
-                    android:layout_height="0dip"
-                    android:layout_weight="1"
-                />
-        </LinearLayout>
-    </LinearLayout>
-
-    <RelativeLayout android:id="@+id/button_bar"
-        android:layout_height="wrap_content"
-        android:layout_width="match_parent"
-        android:layout_weight="0"
-        android:visibility="gone">
-
-        <Button android:id="@+id/back_button"
-            android:layout_width="150dip"
-            android:layout_height="wrap_content"
-            android:layout_margin="5dip"
-            android:layout_alignParentLeft="true"
-            android:text="@string/back_button_label"
-        />
-        <LinearLayout
-            android:orientation="horizontal"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_alignParentRight="true">
-
-            <Button android:id="@+id/skip_button"
-                android:layout_width="150dip"
-                android:layout_height="wrap_content"
-                android:layout_margin="5dip"
-                android:text="@string/skip_button_label"
-                android:visibility="gone"
-            />
-
-            <Button android:id="@+id/next_button"
-                android:layout_width="150dip"
-                android:layout_height="wrap_content"
-                android:layout_margin="5dip"
-                android:text="@string/next_button_label"
-            />
-        </LinearLayout>
-    </RelativeLayout>
-</LinearLayout>
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/layout/preference_list_content.xml b/core/res/res/layout/preference_list_content.xml
index 62181b5..70bc59a 100644
--- a/core/res/res/layout/preference_list_content.xml
+++ b/core/res/res/layout/preference_list_content.xml
@@ -27,8 +27,6 @@
         android:orientation="horizontal"
         android:layout_width="match_parent"
         android:layout_height="0px"
-        android:layout_marginTop="@dimen/preference_screen_top_margin"
-        android:layout_marginBottom="@dimen/preference_screen_bottom_margin"
         android:layout_weight="1">
 
         <LinearLayout
@@ -48,6 +46,7 @@
                 android:paddingRight="@dimen/preference_screen_header_padding_side"
                 android:paddingTop="@dimen/preference_screen_header_vertical_padding"
                 android:paddingBottom="@dimen/preference_screen_header_vertical_padding"
+                android:clipToPadding="false"
                 android:scrollbarStyle="@integer/preference_screen_header_scrollbarStyle"
                 android:drawSelectorOnTop="false"
                 android:cacheColorHint="@android:color/transparent"
@@ -63,11 +62,10 @@
 
         <LinearLayout
                 android:id="@+id/prefs_frame"
+                style="?attr/preferencePanelStyle"
                 android:layout_width="0px"
                 android:layout_height="match_parent"
                 android:layout_weight="@integer/preferences_right_pane_weight"
-                android:layout_marginLeft="@dimen/preference_screen_side_margin"
-                android:layout_marginRight="@dimen/preference_screen_side_margin"
                 android:orientation="vertical"
                 android:visibility="gone" >
 
diff --git a/core/res/res/layout/preference_list_content_single.xml b/core/res/res/layout/preference_list_content_single.xml
index 6902ffd..259869d 100644
--- a/core/res/res/layout/preference_list_content_single.xml
+++ b/core/res/res/layout/preference_list_content_single.xml
@@ -39,6 +39,9 @@
                 android:layout_height="0px"
                 android:layout_weight="1"
                 android:drawSelectorOnTop="false"
+                android:paddingLeft="@dimen/preference_fragment_padding_side"
+                android:paddingRight="@dimen/preference_fragment_padding_side"
+                android:scrollbarStyle="@integer/preference_fragment_scrollbarStyle"
                 android:cacheColorHint="@android:color/transparent"
                 android:listPreferredItemHeight="48dp"
                 android:scrollbarAlwaysDrawVerticalTrack="true" />
diff --git a/core/res/res/values-h720dp/dimens.xml b/core/res/res/values-h720dp/dimens.xml
index 7efe322..6e99183 100644
--- a/core/res/res/values-h720dp/dimens.xml
+++ b/core/res/res/values-h720dp/dimens.xml
@@ -21,10 +21,6 @@
     <dimen name="alert_dialog_button_bar_height">54dip</dimen>
     <!-- Preference fragment padding, bottom -->
     <dimen name="preference_fragment_padding_bottom">16dp</dimen>
-    <!-- Preference activity top margin -->
-    <dimen name="preference_screen_top_margin">16dp</dimen>
-    <!-- Preference activity bottom margin -->
-    <dimen name="preference_screen_bottom_margin">16dp</dimen>
 
     <dimen name="preference_screen_header_padding_side">0dip</dimen>
 
diff --git a/core/res/res/values-large/styles.xml b/core/res/res/values-large/styles.xml
deleted file mode 100644
index 5206d7c..0000000
--- a/core/res/res/values-large/styles.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?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>
-    <style name="PreferencePanel">
-        <item name="android:layout_marginLeft">@dimen/preference_screen_side_margin</item>
-        <item name="android:layout_marginRight">@dimen/preference_screen_side_margin</item>
-        <item name="android:layout_marginTop">48dip</item>
-        <item name="android:layout_marginBottom">48dip</item>
-        <item name="android:background">?attr/detailsElementBackground</item>
-    </style>
-</resources>
diff --git a/core/res/res/values-sw600dp/dimens.xml b/core/res/res/values-sw600dp/dimens.xml
index 24d5d8d..792066e 100644
--- a/core/res/res/values-sw600dp/dimens.xml
+++ b/core/res/res/values-sw600dp/dimens.xml
@@ -45,13 +45,7 @@
     <dimen name="keyguard_pattern_unlock_status_line_font_size">14sp</dimen>
 
     <!-- Preference activity, vertical padding for the header list -->
-    <dimen name="preference_screen_header_vertical_padding">16dp</dimen>
-
-    <!-- Reduce the margin when using dual pane -->
-    <!-- Preference activity side margins -->
-    <dimen name="preference_screen_side_margin">0dp</dimen>
-    <!-- Preference activity side margins negative-->
-    <dimen name="preference_screen_side_margin_negative">-4dp</dimen>
+    <dimen name="preference_screen_header_vertical_padding">32dp</dimen>
 
 </resources>
 
diff --git a/core/res/res/values-sw600dp/styles.xml b/core/res/res/values-sw600dp/styles.xml
index 7dea9b8..f9e95b7 100644
--- a/core/res/res/values-sw600dp/styles.xml
+++ b/core/res/res/values-sw600dp/styles.xml
@@ -25,4 +25,12 @@
         <item name="android:measureWithLargestChild">true</item>
         <item name="android:tabLayout">@android:layout/tab_indicator_holo</item>
     </style>
+
+    <style name="PreferencePanel">
+        <item name="android:layout_marginLeft">@dimen/preference_screen_side_margin</item>
+        <item name="android:layout_marginRight">@dimen/preference_screen_side_margin</item>
+        <item name="android:layout_marginTop">@dimen/preference_screen_top_margin</item>
+        <item name="android:layout_marginBottom">@dimen/preference_screen_bottom_margin</item>
+        <item name="android:background">?attr/detailsElementBackground</item>
+    </style>
 </resources>
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/config.xml b/core/res/res/values/config.xml
index 8fbb09e..b155b803 100755
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -582,21 +582,6 @@
          If false, Content-disposition fragments are ignored -->
     <bool name="config_mms_content_disposition_support">true</bool>
 
-    <!-- If this value is true, the carrier supports sms delivery reports.
-         If false, sms delivery reports are not supported and the preference
-         option to enable/disable delivery reports is removed in the Messaging app. -->
-    <bool name="config_sms_delivery_reports_support">true</bool>
-
-    <!-- If this value is true, the carrier supports mms delivery reports.
-         If false, mms delivery reports are not supported and the preference
-         option to enable/disable delivery reports is removed in the Messaging app. -->
-    <bool name="config_mms_delivery_reports_support">true</bool>
-
-    <!-- If this value is true, the carrier supports mms read reports.
-         If false, mms read reports are not supported and the preference
-         option to enable/disable read reports is removed in the Messaging app. -->
-    <bool name="config_mms_read_reports_support">true</bool>
-
     <!-- National Language Identifier codes for the following two config items.
          (from 3GPP TS 23.038 V9.1.1 Table 6.2.1.2.4.1):
           0  - reserved
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index c522c1e..62a2187 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -78,7 +78,7 @@
     <!-- Preference activity side margins -->
     <dimen name="preference_screen_side_margin">0dp</dimen>
     <!-- Preference activity side margins negative-->
-    <dimen name="preference_screen_side_margin_negative">0dp</dimen>
+    <dimen name="preference_screen_side_margin_negative">-4dp</dimen>
     <!-- Preference activity top margin -->
     <dimen name="preference_screen_top_margin">0dp</dimen>
     <!-- Preference activity bottom margin -->
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
index 44dd899..4f23716 100755
--- a/data/sounds/AudioPackage7.mk
+++ b/data/sounds/AudioPackage7.mk
@@ -53,7 +53,6 @@
 	$(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/Perseus.ogg:system/media/audio/ringtones/Perseus.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 \
diff --git a/docs/html/sdk/eclipse-adt.jd b/docs/html/sdk/eclipse-adt.jd
index 18f47a6..bbf7cbe 100644
--- a/docs/html/sdk/eclipse-adt.jd
+++ b/docs/html/sdk/eclipse-adt.jd
@@ -22,6 +22,11 @@
     </li>
     <li><a href="#updating">Updating the ADT Plugin</a></li>
   </ol>
+  
+  <h2>See also</h2>
+  <ol>
+    <li><a href="{@docRoot}guide/developing/tools/adt.html">Android Developer Tools</a></li>
+  </ol>
 
 </div>
 </div>
@@ -50,6 +55,12 @@
 how to update ADT to the latest version or how to uninstall it, if necessary.
 </p>
 
+<p>For information about the features provided by the ADT plugin, such as code
+editor features, SDK tool integration, and the graphical layout editor (for drag-and-drop layout
+editing), see the <a href="{@docRoot}guide/developing/tools/adt.html">Android Developer Tools</a>
+document.</p>
+
+
 <h2 id="notes">Revisions</h2>
 
 <p>The sections below provide notes about successive releases of
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index 88cfc5a..cedf456 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -194,6 +194,7 @@
 
 void DisplayList::init() {
     mSize = 0;
+    mIsRenderable = true;
 }
 
 size_t DisplayList::getSize() {
@@ -892,7 +893,7 @@
 // Base structure
 ///////////////////////////////////////////////////////////////////////////////
 
-DisplayListRenderer::DisplayListRenderer(): mWriter(MIN_WRITER_SIZE) {
+DisplayListRenderer::DisplayListRenderer(): mWriter(MIN_WRITER_SIZE), mHasDrawOps(false) {
 }
 
 DisplayListRenderer::~DisplayListRenderer() {
@@ -926,6 +927,8 @@
     mPathMap.clear();
 
     mMatrices.clear();
+
+    mHasDrawOps = false;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -938,6 +941,7 @@
     } else {
         displayList->initFromDisplayListRenderer(*this, true);
     }
+    displayList->setRenderable(mHasDrawOps);
     return displayList;
 }
 
@@ -982,7 +986,11 @@
 }
 
 void DisplayListRenderer::restore() {
-    addOp(DisplayList::Restore);
+    if (mRestoreSaveCount < 0) {
+        addOp(DisplayList::Restore);
+    } else {
+        mRestoreSaveCount--;
+    }
     OpenGLRenderer::restore();
 }
 
diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h
index 69e72a4..8cd7fea 100644
--- a/libs/hwui/DisplayListRenderer.h
+++ b/libs/hwui/DisplayListRenderer.h
@@ -63,6 +63,7 @@
     // IMPORTANT: Update the intialization of OP_NAMES in the .cpp file
     //            when modifying this file
     enum Op {
+        // Non-drawing operations
         Save = 0,
         Restore,
         RestoreToCount,
@@ -75,6 +76,7 @@
         SetMatrix,
         ConcatMatrix,
         ClipRect,
+        // Drawing operations
         DrawDisplayList,
         DrawLayer,
         DrawBitmap,
@@ -113,6 +115,14 @@
 
     static void outputLogBuffer(int fd);
 
+    void setRenderable(bool renderable) {
+        mIsRenderable = renderable;
+    }
+
+    bool isRenderable() const {
+        return mIsRenderable;
+    }
+
 private:
     void init();
 
@@ -207,6 +217,8 @@
     mutable SkFlattenableReadBuffer mReader;
 
     size_t mSize;
+
+    bool mIsRenderable;
 };
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -328,6 +340,7 @@
     inline void addOp(DisplayList::Op drawOp) {
         insertRestoreToCount();
         mWriter.writeInt(drawOp);
+        mHasDrawOps = mHasDrawOps || drawOp >= DisplayList::DrawDisplayList;
     }
 
     inline void addInt(int value) {
@@ -479,6 +492,7 @@
     SkWriter32 mWriter;
 
     int mRestoreSaveCount;
+    bool mHasDrawOps;
 
     friend class DisplayList;
 
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 04f3c58..a20a88e 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -1278,7 +1278,7 @@
 
     // All the usual checks and setup operations (quickReject, setupDraw, etc.)
     // will be performed by the display list itself
-    if (displayList) {
+    if (displayList && displayList->isRenderable()) {
         return displayList->replay(*this, dirty, level);
     }
 
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 525ee8b..7f09319 100755
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -2325,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);
diff --git a/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp b/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp
index 2e66a2c..ce07e32 100644
--- a/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp
+++ b/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp
@@ -136,25 +136,29 @@
 void AnotherPacketSource::queueDiscontinuity(
         ATSParser::DiscontinuityType type,
         const sp<AMessage> &extra) {
+    Mutex::Autolock autoLock(mLock);
+
+    // Leave only discontinuities in the queue.
+    List<sp<ABuffer> >::iterator it = mBuffers.begin();
+    while (it != mBuffers.end()) {
+        sp<ABuffer> oldBuffer = *it;
+
+        int32_t oldDiscontinuityType;
+        if (!oldBuffer->meta()->findInt32(
+                    "discontinuity", &oldDiscontinuityType)) {
+            it = mBuffers.erase(it);
+            continue;
+        }
+
+        ++it;
+    }
+
+    mEOSResult = OK;
+
     sp<ABuffer> buffer = new ABuffer(0);
     buffer->meta()->setInt32("discontinuity", static_cast<int32_t>(type));
     buffer->meta()->setMessage("extra", extra);
 
-    Mutex::Autolock autoLock(mLock);
-
-#if 0
-    if (type == ATSParser::DISCONTINUITY_SEEK
-            || type == ATSParser::DISCONTINUITY_FORMATCHANGE) {
-        // XXX Fix this: This will also clear any pending discontinuities,
-        // If there's a pending DISCONTINUITY_FORMATCHANGE and the new
-        // discontinuity is "just" a DISCONTINUITY_SEEK, this will effectively
-        // downgrade the type of discontinuity received by the client.
-
-        mBuffers.clear();
-        mEOSResult = OK;
-    }
-#endif
-
     mBuffers.push_back(buffer);
     mCondition.signal();
 }
diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp
index 10cea22..1f0016a 100644
--- a/opengl/libs/EGL/eglApi.cpp
+++ b/opengl/libs/EGL/eglApi.cpp
@@ -454,13 +454,6 @@
     EGLBoolean result = s->cnx->egl.eglDestroySurface(
             dp->disp[s->impl].dpy, s->surface);
     if (result == EGL_TRUE) {
-        ANativeWindow* const window = s->win.get();
-        if (window != NULL) {
-            native_window_set_buffers_format(window, 0);
-            if (native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL)) {
-                LOGE("EGLNativeWindowType %p disconnected failed", window);
-            }
-        }
         _s.terminate();
     }
     return result;
diff --git a/opengl/libs/EGL/egl_object.h b/opengl/libs/EGL/egl_object.h
index 3459a8a..d2b7378 100644
--- a/opengl/libs/EGL/egl_object.h
+++ b/opengl/libs/EGL/egl_object.h
@@ -125,7 +125,15 @@
 
 class egl_surface_t: public egl_object_t {
 protected:
-    ~egl_surface_t() {}
+    ~egl_surface_t() {
+        ANativeWindow* const window = win.get();
+        if (window != NULL) {
+            native_window_set_buffers_format(window, 0);
+            if (native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL)) {
+                LOGE("EGLNativeWindowType %p disconnected failed", window);
+            }
+        }
+    }
 public:
     typedef egl_object_t::LocalRef<egl_surface_t, EGLSurface> Ref;
 
@@ -232,4 +240,3 @@
 // ----------------------------------------------------------------------------
 
 #endif // ANDROID_EGL_OBJECT_H
-
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-hdpi/status_bar_bg_tile.png b/packages/SystemUI/res/drawable-hdpi/status_bar_bg_tile.png
index 37cad22..aee197c 100644
--- a/packages/SystemUI/res/drawable-hdpi/status_bar_bg_tile.png
+++ b/packages/SystemUI/res/drawable-hdpi/status_bar_bg_tile.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-mdpi/status_bar_bg_tile.png b/packages/SystemUI/res/drawable-mdpi/status_bar_bg_tile.png
index 83d106d..6579ff9 100644
--- a/packages/SystemUI/res/drawable-mdpi/status_bar_bg_tile.png
+++ b/packages/SystemUI/res/drawable-mdpi/status_bar_bg_tile.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/drawable-xhdpi/status_bar_bg_tile.png b/packages/SystemUI/res/drawable-xhdpi/status_bar_bg_tile.png
index 9e21348..d01b117 100644
--- a/packages/SystemUI/res/drawable-xhdpi/status_bar_bg_tile.png
+++ b/packages/SystemUI/res/drawable-xhdpi/status_bar_bg_tile.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/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 6db5fc4..f633825c 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -63,4 +63,28 @@
 
     <!-- thickness (height) of dividers between each notification row -->
     <dimen name="notification_divider_height">1dp</dimen>
+
+    <!-- Notification drawer tuning parameters (phone UI) -->
+    <!-- Initial velocity of the shade when expanding on its own -->
+    <dimen name="self_expand_velocity">2000dp</dimen>
+    <!-- Initial velocity of the shade when collapsing on its own -->
+    <dimen name="self_collapse_velocity">2000dp</dimen>
+    <!-- Minimum final velocity of gestures interpreted as expand requests -->
+    <dimen name="fling_expand_min_velocity">200dp</dimen>
+    <!-- Minimum final velocity of gestures interpreted as collapse requests -->
+    <dimen name="fling_collapse_min_velocity">200dp</dimen>
+    <!-- Cap on contribution of x dimension of gesture to overall velocity -->
+    <dimen name="fling_gesture_max_x_velocity">200dp</dimen>
+
+    <!-- Minimum fraction of the display a gesture must travel, at any velocity, to qualify as a
+         collapse request -->
+    <item type="dimen" name="collapse_min_display_fraction">10%</item>
+    <!-- Minimum fraction of the display a gesture must travel to qualify as an expand request -->
+    <item type="dimen" name="expand_min_display_fraction">50%</item>
+
+    <!-- Initial acceleration of an expand animation after fling -->
+    <dimen name="expand_accel">2000dp</dimen>
+    <!-- Initial acceleration of an collapse animation after fling -->
+    <dimen name="collapse_accel">2000dp</dimen>
+
 </resources>
diff --git a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
index 5a3850d..049a284 100644
--- a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
+++ b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
@@ -58,7 +58,7 @@
     private static final boolean DEBUG = false;
 
     static final boolean FIXED_SIZED_SURFACE = true;
-    static final boolean USE_OPENGL = false;
+    static final boolean USE_OPENGL = true;
 
     WallpaperManager mWallpaperManager;
 
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..6e6567b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -112,6 +112,18 @@
     // will likely move to a resource or other tunable param at some point
     private static final int INTRUDER_ALERT_DECAY_MS = 10000;
 
+    // fling gesture tuning parameters, scaled to display density
+    private float mSelfExpandVelocityPx; // classic value: 2000px/s
+    private float mSelfCollapseVelocityPx; // classic value: 2000px/s (will be negated to collapse "up")
+    private float mFlingExpandMinVelocityPx; // classic value: 200px/s
+    private float mFlingCollapseMinVelocityPx; // classic value: 200px/s
+    private float mCollapseMinDisplayFraction; // classic value: 0.08 (25px/min(320px,480px) on G1)
+    private float mExpandMinDisplayFraction; // classic value: 0.5 (drag open halfway to expand)
+    private float mFlingGestureMaxXVelocityPx; // classic value: 150px/s
+
+    private float mExpandAccelPx; // classic value: 2000px/s/s
+    private float mCollapseAccelPx; // classic value: 2000px/s/s (will be negated to collapse "up")
+
     PhoneStatusBarPolicy mIconPolicy;
 
     // These are no longer handled by the policy, because we need custom strategies for them
@@ -475,6 +487,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) {
@@ -1175,7 +1191,7 @@
         }
 
         prepareTracking(0, true);
-        performFling(0, 2000.0f, true);
+        performFling(0, mSelfExpandVelocityPx, true);
     }
 
     public void animateCollapse() {
@@ -1211,7 +1227,7 @@
         // and doesn't try to re-open the windowshade.
         mExpanded = true;
         prepareTracking(y, false);
-        performFling(y, -2000.0f, true);
+        performFling(y, -mSelfCollapseVelocityPx, true);
     }
 
     void performExpand() {
@@ -1327,8 +1343,8 @@
         mTracking = true;
         mVelocityTracker = VelocityTracker.obtain();
         if (opening) {
-            mAnimAccel = 2000.0f;
-            mAnimVel = 200;
+            mAnimAccel = mExpandAccelPx;
+            mAnimVel = mFlingExpandMinVelocityPx;
             mAnimY = mStatusBarView.getHeight();
             updateExpandedViewPos((int)mAnimY);
             mAnimating = true;
@@ -1366,29 +1382,31 @@
 
         if (mExpanded) {
             if (!always && (
-                    vel > 200.0f
-                    || (y > (mDisplayMetrics.heightPixels-25) && vel > -200.0f))) {
+                    vel > mFlingCollapseMinVelocityPx
+                    || (y > (mDisplayMetrics.heightPixels*(1f-mCollapseMinDisplayFraction)) &&
+                        vel > -mFlingExpandMinVelocityPx))) {
                 // We are expanded, but they didn't move sufficiently to cause
                 // us to retract.  Animate back to the expanded position.
-                mAnimAccel = 2000.0f;
+                mAnimAccel = mExpandAccelPx;
                 if (vel < 0) {
                     mAnimVel = 0;
                 }
             }
             else {
                 // We are expanded and are now going to animate away.
-                mAnimAccel = -2000.0f;
+                mAnimAccel = -mCollapseAccelPx;
                 if (vel > 0) {
                     mAnimVel = 0;
                 }
             }
         } else {
             if (always || (
-                    vel > 200.0f
-                    || (y > (mDisplayMetrics.heightPixels/2) && vel > -200.0f))) {
+                    vel > mFlingExpandMinVelocityPx
+                    || (y > (mDisplayMetrics.heightPixels*(1f-mExpandMinDisplayFraction)) &&
+                        vel > -mFlingCollapseMinVelocityPx))) {
                 // We are collapsed, and they moved enough to allow us to
                 // expand.  Animate in the notifications.
-                mAnimAccel = 2000.0f;
+                mAnimAccel = mExpandAccelPx;
                 if (vel < 0) {
                     mAnimVel = 0;
                 }
@@ -1396,7 +1414,7 @@
             else {
                 // We are collapsed, but they didn't move sufficiently to cause
                 // us to retract.  Animate back to the collapsed position.
-                mAnimAccel = -2000.0f;
+                mAnimAccel = -mCollapseAccelPx;
                 if (vel > 0) {
                     mAnimVel = 0;
                 }
@@ -1476,8 +1494,8 @@
                 if (xVel < 0) {
                     xVel = -xVel;
                 }
-                if (xVel > 150.0f) {
-                    xVel = 150.0f; // limit how much we care about the x axis
+                if (xVel > mFlingGestureMaxXVelocityPx) {
+                    xVel = mFlingGestureMaxXVelocityPx; // limit how much we care about the x axis
                 }
 
                 float vel = (float)Math.hypot(yVel, xVel);
@@ -1485,6 +1503,14 @@
                     vel = -vel;
                 }
 
+                if (CHATTY) {
+                    Slog.d(TAG, String.format("gesture: vraw=(%f,%f) vnorm=(%f,%f) vlinear=%f", 
+                        mVelocityTracker.getXVelocity(), 
+                        mVelocityTracker.getYVelocity(),
+                        xVel, yVel,
+                        vel));
+                }
+
                 performFling((int)event.getRawY(), vel, false);
             }
 
@@ -2129,6 +2155,19 @@
 
         mEdgeBorder = res.getDimensionPixelSize(R.dimen.status_bar_edge_ignore);
 
+        mSelfExpandVelocityPx = res.getDimension(R.dimen.self_expand_velocity);
+        mSelfCollapseVelocityPx = res.getDimension(R.dimen.self_collapse_velocity);
+        mFlingExpandMinVelocityPx = res.getDimension(R.dimen.fling_expand_min_velocity);
+        mFlingCollapseMinVelocityPx = res.getDimension(R.dimen.fling_collapse_min_velocity);
+
+        mCollapseMinDisplayFraction = res.getFraction(R.dimen.collapse_min_display_fraction, 1, 1);
+        mExpandMinDisplayFraction = res.getFraction(R.dimen.expand_min_display_fraction, 1, 1);
+
+        mExpandAccelPx = res.getDimension(R.dimen.expand_accel);
+        mCollapseAccelPx = res.getDimension(R.dimen.collapse_accel);
+
+        mFlingGestureMaxXVelocityPx = res.getDimension(R.dimen.fling_gesture_max_x_velocity);
+
         if (false) Slog.v(TAG, "updateResources");
     }
 
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/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index be129a8..dfd1b00 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -124,6 +124,7 @@
 import android.view.WindowManagerImpl;
 import android.view.WindowManagerPolicy;
 import android.view.KeyCharacterMap.FallbackAction;
+import android.view.accessibility.AccessibilityEvent;
 import android.view.animation.Animation;
 import android.view.animation.AnimationUtils;
 import android.media.IAudioService;
@@ -3104,7 +3105,29 @@
         mHandler.post(new Runnable() {
             @Override public void run() {
                 if (mBootMsgDialog == null) {
-                    mBootMsgDialog = new ProgressDialog(mContext);
+                    mBootMsgDialog = new ProgressDialog(mContext) {
+                        // This dialog will consume all events coming in to
+                        // it, to avoid it trying to do things too early in boot.
+                        @Override public boolean dispatchKeyEvent(KeyEvent event) {
+                            return true;
+                        }
+                        @Override public boolean dispatchKeyShortcutEvent(KeyEvent event) {
+                            return true;
+                        }
+                        @Override public boolean dispatchTouchEvent(MotionEvent ev) {
+                            return true;
+                        }
+                        @Override public boolean dispatchTrackballEvent(MotionEvent ev) {
+                            return true;
+                        }
+                        @Override public boolean dispatchGenericMotionEvent(MotionEvent ev) {
+                            return true;
+                        }
+                        @Override public boolean dispatchPopulateAccessibilityEvent(
+                                AccessibilityEvent event) {
+                            return true;
+                        }
+                    };
                     mBootMsgDialog.setTitle(R.string.android_upgrading_title);
                     mBootMsgDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
                     mBootMsgDialog.setIndeterminate(true);
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/SystemServer.java b/services/java/com/android/server/SystemServer.java
index e6f92a5..d0e8b5e 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -182,7 +182,7 @@
 
             // only initialize the power service after we have started the
             // lights service, content providers and the battery service.
-            power.init(context, lights, ActivityManagerService.getDefault(), battery);
+            power.init(context, lights, ActivityManagerService.self(), battery);
 
             Slog.i(TAG, "Alarm Manager");
             alarm = new AlarmManagerService(context);
@@ -197,8 +197,7 @@
                     factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL);
             ServiceManager.addService(Context.WINDOW_SERVICE, wm);
 
-            ((ActivityManagerService)ServiceManager.getService("activity"))
-                    .setWindowManager(wm);
+            ActivityManagerService.self().setWindowManager(wm);
 
             // Skip Bluetooth if we have an emulator kernel
             // TODO: Use a more reliable check to see if this product should
@@ -265,7 +264,7 @@
         } catch (Throwable e) {
             reportWtf("making display ready", e);
         }
- 
+
         try {
             pm.performBootDexOpt();
         } catch (Throwable e) {
@@ -618,8 +617,7 @@
         // where third party code can really run (but before it has actually
         // started launching the initial applications), for us to complete our
         // initialization.
-        ((ActivityManagerService)ActivityManagerNative.getDefault())
-                .systemReady(new Runnable() {
+        ActivityManagerService.self().systemReady(new Runnable() {
             public void run() {
                 Slog.i(TAG, "Making services ready");
 
diff --git a/services/java/com/android/server/TelephonyRegistry.java b/services/java/com/android/server/TelephonyRegistry.java
index dd54c16..4447ad0 100644
--- a/services/java/com/android/server/TelephonyRegistry.java
+++ b/services/java/com/android/server/TelephonyRegistry.java
@@ -421,11 +421,13 @@
                 modified = true;
             }
             if (modified) {
-                Slog.d(TAG, "onDataConnectionStateChanged(" + state + ", " + networkType + ")");
+                Slog.d(TAG, "onDataConnectionStateChanged(" + mDataConnectionState
+                        + ", " + mDataConnectionNetworkType + ")");
                 for (Record r : mRecords) {
                     if ((r.events & PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) != 0) {
                         try {
-                            r.callback.onDataConnectionStateChanged(state, networkType);
+                            r.callback.onDataConnectionStateChanged(mDataConnectionState,
+                                    mDataConnectionNetworkType);
                         } catch (RemoteException ex) {
                             mRemoveList.add(r.binder);
                         }
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 565063a..6ceccaf 100644
--- a/services/java/com/android/server/WallpaperManagerService.java
+++ b/services/java/com/android/server/WallpaperManagerService.java
@@ -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 7232a94..bb5e989 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -91,7 +91,6 @@
 import android.os.FileObserver;
 import android.os.FileUtils;
 import android.os.Handler;
-import android.os.HandlerThread;
 import android.os.IBinder;
 import android.os.IPermissionController;
 import android.os.Looper;
@@ -5518,6 +5517,48 @@
         return msg;
     }
 
+    boolean incProviderCount(ProcessRecord r, ContentProviderRecord cpr) {
+        if (r != null) {
+            Integer cnt = r.conProviders.get(cpr);
+            if (DEBUG_PROVIDER) Slog.v(TAG,
+                    "Adding provider requested by "
+                    + r.processName + " from process "
+                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
+                    + " cnt=" + (cnt == null ? 1 : cnt));
+            if (cnt == null) {
+                cpr.clients.add(r);
+                r.conProviders.put(cpr, new Integer(1));
+                return true;
+            } else {
+                r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
+            }
+        } else {
+            cpr.externals++;
+        }
+        return false;
+    }
+
+    boolean decProviderCount(ProcessRecord r, ContentProviderRecord cpr) {
+        if (r != null) {
+            Integer cnt = r.conProviders.get(cpr);
+            if (DEBUG_PROVIDER) Slog.v(TAG,
+                    "Removing provider requested by "
+                    + r.processName + " from process "
+                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
+                    + " cnt=" + cnt);
+            if (cnt == null || cnt.intValue() <= 1) {
+                cpr.clients.remove(r);
+                r.conProviders.remove(cpr);
+                return true;
+            } else {
+                r.conProviders.put(cpr, new Integer(cnt.intValue()-1));
+            }
+        } else {
+            cpr.externals++;
+        }
+        return false;
+    }
+
     private final ContentProviderHolder getContentProviderImpl(
         IApplicationThread caller, String name) {
         ContentProviderRecord cpr;
@@ -5537,7 +5578,8 @@
 
             // First check if this content provider has been published...
             cpr = mProvidersByName.get(name);
-            if (cpr != null) {
+            boolean providerRunning = cpr != null;
+            if (providerRunning) {
                 cpi = cpr.info;
                 String msg;
                 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
@@ -5561,18 +5603,8 @@
 
                 // In this case the provider instance already exists, so we can
                 // return it right away.
-                if (r != null) {
-                    if (DEBUG_PROVIDER) Slog.v(TAG,
-                            "Adding provider requested by "
-                            + r.processName + " from process "
-                            + cpr.info.processName);
-                    Integer cnt = r.conProviders.get(cpr);
-                    if (cnt == null) {
-                        r.conProviders.put(cpr, new Integer(1));
-                    } else {
-                        r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
-                    }
-                    cpr.clients.add(r);
+                final boolean countChanged = incProviderCount(r, cpr);
+                if (countChanged) {
                     if (cpr.app != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
                         // If this is a perceptible app accessing the provider,
                         // make sure to count it as being accessed and thus
@@ -5580,17 +5612,46 @@
                         // content providers are often expensive to start.
                         updateLruProcessLocked(cpr.app, false, true);
                     }
-                } else {
-                    cpr.externals++;
                 }
 
                 if (cpr.app != null) {
-                    updateOomAdjLocked(cpr.app);
+                    if (false) {
+                        if (cpr.name.flattenToShortString().equals(
+                                "com.android.providers.calendar/.CalendarProvider2")) {
+                            Slog.v(TAG, "****************** KILLING "
+                                + cpr.name.flattenToShortString());
+                            Process.killProcess(cpr.app.pid);
+                        }
+                    }
+                    boolean success = updateOomAdjLocked(cpr.app);
+                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
+                    // NOTE: there is still a race here where a signal could be
+                    // pending on the process even though we managed to update its
+                    // adj level.  Not sure what to do about this, but at least
+                    // the race is now smaller.
+                    if (!success) {
+                        // Uh oh...  it looks like the provider's process
+                        // has been killed on us.  We need to wait for a new
+                        // process to be started, and make sure its death
+                        // doesn't kill our process.
+                        Slog.i(TAG,
+                                "Existing provider " + cpr.name.flattenToShortString()
+                                + " is crashing; detaching " + r);
+                        boolean lastRef = decProviderCount(r, cpr);
+                        appDiedLocked(cpr.app, cpr.app.pid, cpr.app.thread);
+                        if (!lastRef) {
+                            // This wasn't the last ref our process had on
+                            // the provider...  we have now been killed, bail.
+                            return null;
+                        }
+                        providerRunning = false;
+                    }
                 }
 
                 Binder.restoreCallingIdentity(origId);
+            }
 
-            } else {
+            if (!providerRunning) {
                 try {
                     cpi = AppGlobals.getPackageManager().
                         resolveContentProvider(name,
@@ -5701,22 +5762,7 @@
                     mProvidersByClass.put(comp, cpr);
                 }
                 mProvidersByName.put(name, cpr);
-
-                if (r != null) {
-                    if (DEBUG_PROVIDER) Slog.v(TAG,
-                            "Adding provider requested by "
-                            + r.processName + " from process "
-                            + cpr.info.processName);
-                    Integer cnt = r.conProviders.get(cpr);
-                    if (cnt == null) {
-                        r.conProviders.put(cpr, new Integer(1));
-                    } else {
-                        r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
-                    }
-                    cpr.clients.add(r);
-                } else {
-                    cpr.externals++;
-                }
+                incProviderCount(r, cpr);
             }
         }
 
@@ -5780,24 +5826,16 @@
             //update content provider record entry info
             ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
             ContentProviderRecord localCpr = mProvidersByClass.get(comp);
-            if (DEBUG_PROVIDER) Slog.v(TAG, "Removing provider requested by "
-                    + r.info.processName + " from process "
-                    + localCpr.appInfo.processName);
             if (localCpr.app == r) {
                 //should not happen. taken care of as a local provider
                 Slog.w(TAG, "removeContentProvider called on local provider: "
                         + cpr.info.name + " in process " + r.processName);
                 return;
             } else {
-                Integer cnt = r.conProviders.get(localCpr);
-                if (cnt == null || cnt.intValue() <= 1) {
-                    localCpr.clients.remove(r);
-                    r.conProviders.remove(localCpr);
-                } else {
-                    r.conProviders.put(localCpr, new Integer(cnt.intValue()-1));
+                if (decProviderCount(r, localCpr)) {
+                    updateOomAdjLocked();
                 }
             }
-            updateOomAdjLocked();
         }
     }
 
@@ -13458,16 +13496,18 @@
         }
     }
 
-    private final void updateOomAdjLocked(
+    private final boolean updateOomAdjLocked(
             ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP) {
         app.hiddenAdj = hiddenAdj;
 
         if (app.thread == null) {
-            return;
+            return false;
         }
 
         final boolean wasKeeping = app.keeping;
 
+        boolean success = true;
+
         computeOomAdjLocked(app, hiddenAdj, TOP_APP, false);
 
         if (app.curRawAdj != app.setRawAdj) {
@@ -13504,6 +13544,7 @@
                     " oom adj to " + app.curAdj + " because " + app.adjType);
                 app.setAdj = app.curAdj;
             } else {
+                success = false;
                 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
             }
         }
@@ -13518,6 +13559,7 @@
                 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
                         app.processName, app.setAdj, app.waitingToKill);
                 Process.killProcessQuiet(app.pid);
+                success = false;
             } else {
                 if (true) {
                     long oldId = Binder.clearCallingIdentity();
@@ -13540,6 +13582,7 @@
                 }
             }
         }
+        return success;
     }
 
     private final ActivityRecord resumedAppLocked() {
@@ -13553,7 +13596,7 @@
         return resumedActivity;
     }
 
-    private final void updateOomAdjLocked(ProcessRecord app) {
+    private final boolean updateOomAdjLocked(ProcessRecord app) {
         final ActivityRecord TOP_ACT = resumedAppLocked();
         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
         int curAdj = app.curAdj;
@@ -13562,7 +13605,7 @@
 
         mAdjSeq++;
 
-        updateOomAdjLocked(app, app.hiddenAdj, TOP_APP);
+        boolean success = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP);
         final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
             && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
         if (nowHidden != wasHidden) {
@@ -13570,6 +13613,7 @@
             // list may also be changed.
             updateOomAdjLocked();
         }
+        return success;
     }
 
     final void updateOomAdjLocked() {
diff --git a/services/java/com/android/server/am/ProcessList.java b/services/java/com/android/server/am/ProcessList.java
index dfcc0bfa..131255f 100644
--- a/services/java/com/android/server/am/ProcessList.java
+++ b/services/java/com/android/server/am/ProcessList.java
@@ -163,7 +163,7 @@
         int minSize = 320*480;  //  153600
         int maxSize = 1280*800; // 1024000  230400 870400  .264
         float scaleDisp = ((float)(displayWidth*displayHeight)-minSize)/(maxSize-minSize);
-        Slog.i("XXXXXX", "scaleDisp=" + scaleDisp + " dw=" + displayWidth + " dh=" + displayHeight);
+        //Slog.i("XXXXXX", "scaleDisp=" + scaleDisp + " dw=" + displayWidth + " dh=" + displayHeight);
 
         StringBuilder adjString = new StringBuilder();
         StringBuilder memString = new StringBuilder();
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/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/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
index c8671c1..00fb0e0 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
@@ -576,7 +576,8 @@
         boolean allowed =
                     (gprsState == ServiceState.STATE_IN_SERVICE || mAutoAttachOnCreation) &&
                     mPhone.mIccRecords.getRecordsLoaded() &&
-                    mPhone.getState() == Phone.State.IDLE &&
+                    (mPhone.getState() == Phone.State.IDLE ||
+                     mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) &&
                     internalDataEnabled &&
                     (!mPhone.getServiceState().getRoaming() || getDataOnRoamingEnabled()) &&
                     !mIsPsRestricted &&
@@ -587,8 +588,10 @@
                 reason += " - gprs= " + gprsState;
             }
             if (!mPhone.mIccRecords.getRecordsLoaded()) reason += " - SIM not loaded";
-            if (mPhone.getState() != Phone.State.IDLE) {
+            if (mPhone.getState() != Phone.State.IDLE &&
+                    !mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
                 reason += " - PhoneState= " + mPhone.getState();
+                reason += " - Concurrent voice and data not allowed";
             }
             if (!internalDataEnabled) reason += " - mInternalDataEnabled= false";
             if (mPhone.getServiceState().getRoaming() && !getDataOnRoamingEnabled()) {
diff --git a/wifi/java/android/net/wifi/WifiNative.java b/wifi/java/android/net/wifi/WifiNative.java
index 6c6f149..c1f6785 100644
--- a/wifi/java/android/net/wifi/WifiNative.java
+++ b/wifi/java/android/net/wifi/WifiNative.java
@@ -243,7 +243,7 @@
 
     /* p2p_connect <peer device address> <pbc|pin|PIN#> [label|display|keypad]
         [persistent] [join|auth] [go_intent=<0..15>] [freq=<in MHz>] */
-    public static String p2pConnect(WifiP2pConfig config) {
+    public static String p2pConnect(WifiP2pConfig config, boolean joinExistingGroup) {
         if (config == null) return null;
         List<String> args = new ArrayList<String>();
         WpsConfiguration wpsConfig = config.wpsConfig;
@@ -269,15 +269,15 @@
                 break;
         }
 
-        if (config.isPersistent) args.add("persistent");
-        if (config.joinExistingGroup) args.add("join");
+        /* Persist unless there is an explicit request to not do so*/
+        if (config.persist != WifiP2pConfig.Persist.NO) args.add("persistent");
+        if (joinExistingGroup) args.add("join");
 
         int groupOwnerIntent = config.groupOwnerIntent;
         if (groupOwnerIntent < 0 || groupOwnerIntent > 15) {
             groupOwnerIntent = 3; //default value
         }
         args.add("go_intent=" + groupOwnerIntent);
-        if (config.channel > 0) args.add("freq=" + config.channel);
 
         String command = "P2P_CONNECT ";
         for (String s : args) command += s + " ";
@@ -300,11 +300,24 @@
 
     /* Invite a peer to a group */
     public static boolean p2pInvite(WifiP2pGroup group, String deviceAddress) {
-        if (group == null || deviceAddress == null) return false;
-        return doBooleanCommand("P2P_INVITE group=" + group.getInterface()
-                + " peer=" + deviceAddress + " go_dev_addr=" + group.getOwner().deviceAddress);
+        if (deviceAddress == null) return false;
+
+        if (group == null) {
+            return doBooleanCommand("P2P_INVITE peer=" + deviceAddress);
+        } else {
+            return doBooleanCommand("P2P_INVITE group=" + group.getInterface()
+                    + " peer=" + deviceAddress + " go_dev_addr=" + group.getOwner().deviceAddress);
+        }
     }
 
+    /* Reinvoke a persistent connection */
+    public static boolean p2pReinvoke(int netId, String deviceAddress) {
+        if (deviceAddress == null || netId < 0) return false;
+
+        return doBooleanCommand("P2P_INVITE persistent=" + netId + " peer=" + deviceAddress);
+    }
+
+
     public static String p2pGetInterfaceAddress(String deviceAddress) {
         if (deviceAddress == null) return null;
 
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java b/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java
index b77fd76..2d57363 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java
@@ -51,14 +51,16 @@
      */
     public int groupOwnerIntent = -1;
 
-    public boolean isPersistent;
-
-    public boolean joinExistingGroup;
-
     /**
-     * Channel frequency in MHz
+     * Indicates whether the configuration is saved
      */
-    public int channel;
+    public enum Persist {
+        SYSTEM_DEFAULT,
+        YES,
+        NO
+    }
+
+    public Persist persist = Persist.SYSTEM_DEFAULT;
 
     public WifiP2pConfig() {
         //set defaults
@@ -112,9 +114,7 @@
         sbuf.append("\n address: ").append(deviceAddress);
         sbuf.append("\n wps: ").append(wpsConfig);
         sbuf.append("\n groupOwnerIntent: ").append(groupOwnerIntent);
-        sbuf.append("\n isPersistent: ").append(isPersistent);
-        sbuf.append("\n joinExistingGroup: ").append(joinExistingGroup);
-        sbuf.append("\n channel: ").append(channel);
+        sbuf.append("\n persist: ").append(persist.toString());
         return sbuf.toString();
     }
 
@@ -136,9 +136,7 @@
         dest.writeString(deviceAddress);
         dest.writeParcelable(wpsConfig, flags);
         dest.writeInt(groupOwnerIntent);
-        dest.writeInt(isPersistent ? 1 : 0);
-        dest.writeInt(joinExistingGroup ? 1 : 0);
-        dest.writeInt(channel);
+        dest.writeString(persist.name());
     }
 
     /** Implement the Parcelable interface {@hide} */
@@ -150,9 +148,7 @@
                 config.deviceAddress = in.readString();
                 config.wpsConfig = (WpsConfiguration) in.readParcelable(null);
                 config.groupOwnerIntent = in.readInt();
-                config.isPersistent = (in.readInt() == 1);
-                config.joinExistingGroup = (in.readInt() == 1);
-                config.channel = in.readInt();
+                config.persist = Persist.valueOf(in.readString());
                 return config;
             }
 
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.java b/wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.java
index 4ec23b8..50f624a 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.java
@@ -51,8 +51,10 @@
         }
     }
 
-    public void clear() {
+    public boolean clear() {
+        if (mDevices.isEmpty()) return false;
         mDevices.clear();
+        return true;
     }
 
     public void add(WifiP2pDevice device) {
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pStatus.aidl b/wifi/java/android/net/wifi/p2p/WifiP2pInfo.aidl
similarity index 95%
rename from wifi/java/android/net/wifi/p2p/WifiP2pStatus.aidl
rename to wifi/java/android/net/wifi/p2p/WifiP2pInfo.aidl
index 7bab5d3..a347148 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pStatus.aidl
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pInfo.aidl
@@ -16,4 +16,4 @@
 
 package android.net.wifi.p2p;
 
-parcelable WifiP2pStatus;
+parcelable WifiP2pInfo;
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pInfo.java b/wifi/java/android/net/wifi/p2p/WifiP2pInfo.java
new file mode 100644
index 0000000..9dc2fbf
--- /dev/null
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pInfo.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi.p2p;
+
+import android.os.Parcelable;
+import android.os.Parcel;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+/**
+ * A class representing connection info on Wi-fi P2p
+ * @hide
+ */
+public class WifiP2pInfo implements Parcelable {
+
+    public boolean groupFormed;
+
+    public boolean isGroupOwner;
+
+    public InetAddress groupOwnerAddress;
+
+    public WifiP2pInfo() {
+    }
+
+    public String toString() {
+        StringBuffer sbuf = new StringBuffer();
+        sbuf.append("groupFormed: ").append(groupFormed)
+            .append("isGroupOwner: ").append(isGroupOwner)
+            .append("groupOwnerAddress: ").append(groupOwnerAddress);
+        return sbuf.toString();
+    }
+
+    /** Implement the Parcelable interface {@hide} */
+    public int describeContents() {
+        return 0;
+    }
+
+    /** copy constructor {@hide} */
+    public WifiP2pInfo(WifiP2pInfo source) {
+        if (source != null) {
+            groupFormed = source.groupFormed;
+            isGroupOwner = source.isGroupOwner;
+            groupOwnerAddress = source.groupOwnerAddress;
+       }
+    }
+
+    /** Implement the Parcelable interface {@hide} */
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeByte(groupFormed ? (byte)1 : (byte)0);
+        dest.writeByte(isGroupOwner ? (byte)1 : (byte)0);
+
+        if (groupOwnerAddress != null) {
+            dest.writeByte((byte)1);
+            dest.writeByteArray(groupOwnerAddress.getAddress());
+        } else {
+            dest.writeByte((byte)0);
+        }
+    }
+
+    /** Implement the Parcelable interface {@hide} */
+    public static final Creator<WifiP2pInfo> CREATOR =
+        new Creator<WifiP2pInfo>() {
+            public WifiP2pInfo createFromParcel(Parcel in) {
+                WifiP2pInfo info = new WifiP2pInfo();
+                info.groupFormed = (in.readByte() == 1);
+                info.isGroupOwner = (in.readByte() == 1);
+                if (in.readByte() == 1) {
+                    try {
+                        info.groupOwnerAddress = InetAddress.getByAddress(in.createByteArray());
+                    } catch (UnknownHostException e) {}
+                }
+                return info;
+            }
+
+            public WifiP2pInfo[] newArray(int size) {
+                return new WifiP2pInfo[size];
+            }
+        };
+}
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
index cc1f062..25daf1c 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
@@ -95,6 +95,12 @@
         "android.net.wifi.CONNECTION_STATE_CHANGE";
 
     /**
+     * The lookup key for a {@link android.net.wifi.p2p.WifiP2pInfo} object
+     * Retrieve with {@link android.content.Intent#getParcelableExtra(String)}.
+     */
+    public static final String EXTRA_WIFI_P2P_INFO = "wifiP2pInfo";
+
+    /**
      * The lookup key for a {@link android.net.NetworkInfo} object associated with the
      * Wi-Fi network. Retrieve with
      * {@link android.content.Intent#getParcelableExtra(String)}.
@@ -145,57 +151,38 @@
     public static final int ENABLE_P2P_FAILED                       = BASE + 2;
     public static final int ENABLE_P2P_SUCCEEDED                    = BASE + 3;
 
-    /* arg1 on ENABLE_P2P_FAILED indicates a reason for failure */
+    public static final int DISABLE_P2P                             = BASE + 4;
+    public static final int DISABLE_P2P_FAILED                      = BASE + 5;
+    public static final int DISABLE_P2P_SUCCEEDED                   = BASE + 6;
+
+    public static final int DISCOVER_PEERS                          = BASE + 7;
+    public static final int DISCOVER_PEERS_FAILED                   = BASE + 8;
+    public static final int DISCOVER_PEERS_SUCCEEDED                = BASE + 9;
+
+    public static final int CONNECT                                 = BASE + 10;
+    public static final int CONNECT_FAILED                          = BASE + 11;
+    public static final int CONNECT_SUCCEEDED                       = BASE + 12;
+
+    public static final int CREATE_GROUP                            = BASE + 13;
+    public static final int CREATE_GROUP_FAILED                     = BASE + 14;
+    public static final int CREATE_GROUP_SUCCEEDED                  = BASE + 15;
+
+    public static final int REMOVE_GROUP                            = BASE + 16;
+    public static final int REMOVE_GROUP_FAILED                     = BASE + 17;
+    public static final int REMOVE_GROUP_SUCCEEDED                  = BASE + 18;
+
+    public static final int REQUEST_PEERS                           = BASE + 19;
+    public static final int RESPONSE_PEERS                          = BASE + 20;
+
+    public static final int REQUEST_CONNECTION_INFO                 = BASE + 21;
+    public static final int RESPONSE_CONNECTION_INFO                = BASE + 22;
+
+    /* arg1 values on response messages from the framework */
     public static final int P2P_UNSUPPORTED     = 1;
 
-    public static final int DISABLE_P2P                             = BASE + 5;
-    public static final int DISABLE_P2P_FAILED                      = BASE + 6;
-    public static final int DISABLE_P2P_SUCCEEDED                   = BASE + 7;
-
-    public static final int START_LISTEN_MODE                       = BASE + 9;
-    public static final int START_LISTEN_FAILED                     = BASE + 10;
-    public static final int START_LISTEN_SUCCEEDED                  = BASE + 11;
-
-    public static final int DISCOVER_PEERS                          = BASE + 13;
-    public static final int DISCOVER_PEERS_FAILED                   = BASE + 14;
-    public static final int DISCOVER_PEERS_SUCCEDED                 = BASE + 15;
-
-    public static final int CANCEL_DISCOVER_PEERS                   = BASE + 17;
-    public static final int CANCEL_DISCOVER_PEERS_FAILED            = BASE + 18;
-    public static final int CANCEL_DISCOVER_PEERS_SUCCEDED          = BASE + 19;
-
-    public static final int CONNECT                                 = BASE + 21;
-    public static final int CONNECT_FAILED                          = BASE + 22;
-    public static final int CONNECT_SUCCEEDED                       = BASE + 23;
-
-    public static final int CANCEL_CONNECT                          = BASE + 25;
-    public static final int CANCEL_CONNECT_FAILED                   = BASE + 26;
-    public static final int CANCEL_CONNECT_SUCCEDED                 = BASE + 27;
-
-    public static final int REJECT                                  = BASE + 28;
-    public static final int REJECT_FAILED                           = BASE + 29;
-    public static final int REJECT_SUCCEEDED                        = BASE + 30;
-
-    public static final int CREATE_GROUP                            = BASE + 31;
-    public static final int CREATE_GROUP_FAILED                     = BASE + 32;
-    public static final int CREATE_GROUP_SUCCEEDED                  = BASE + 33;
-
-    public static final int REMOVE_GROUP                            = BASE + 34;
-    public static final int REMOVE_GROUP_FAILED                     = BASE + 35;
-    public static final int REMOVE_GROUP_SUCCEEDED                  = BASE + 36;
-
-    public static final int REQUEST_SETTINGS                        = BASE + 37;
-    public static final int RESPONSE_SETTINGS                       = BASE + 38;
-
-    public static final int REQUEST_PEERS                           = BASE + 39;
-    public static final int RESPONSE_PEERS                          = BASE + 40;
-
-    public static final int REQUEST_CONNECTION_STATUS               = BASE + 41;
-    public static final int RESPONSE_CONNECTION_STATUS              = BASE + 42;
-
-    public static final int WPS_PBC                                 = BASE + 43;
-    public static final int WPS_PIN                                 = BASE + 44;
-    public static final int WPS_PIN_AVAILABLE                       = BASE + 45;
+    public static final int WPS_PBC                                 = BASE + 23;
+    public static final int WPS_PIN                                 = BASE + 24;
+    public static final int WPS_PIN_AVAILABLE                       = BASE + 25;
 
     /**
      * Create a new WifiP2pManager instance. Applications use
@@ -269,17 +256,6 @@
     }
 
     /**
-     * Set device in listen mode. This will make the device discoverable by
-     * another peer.
-     * A dialog to the user is thrown to request his permission since it can
-     * have a significant impact on power consumption
-     */
-     public void setListenState(Channel c, int timeout) {
-        if (c == null) return;
-        c.mAsyncChannel.sendMessage(START_LISTEN_MODE, timeout);
-     }
-
-    /**
      * Initiates peer discovery
      */
     public void discoverPeers(Channel c) {
@@ -288,22 +264,6 @@
     }
 
     /**
-     * Initiates peer discovery with a timeout
-     */
-    public void discoverPeers(Channel c, int timeout) {
-        if (c == null) return;
-        c.mAsyncChannel.sendMessage(DISCOVER_PEERS, timeout);
-    }
-
-    /**
-     * Cancel any existing peer discovery operation
-     */
-    public void cancelPeerDiscovery(Channel c) {
-        if (c == null) return;
-        c.mAsyncChannel.sendMessage(CANCEL_DISCOVER_PEERS);
-    }
-
-    /**
      * Start a p2p connection
      *
      * @param peer Configuration described in a {@link WifiP2pConfig} object.
@@ -314,14 +274,6 @@
     }
 
     /**
-     * Cancel any ongoing negotiation or disconnect from an existing group
-     */
-    public void disconnect(Channel c) {
-        if (c == null) return;
-        c.mAsyncChannel.sendMessage(CANCEL_CONNECT);
-    }
-
-    /**
      * Create a p2p group. This is essentially an access point that can accept
      * client connections.
      */
@@ -340,15 +292,6 @@
     }
 
     /**
-     * Request current p2p settings. This returns a RESPONSE_SETTINGS on the source
-     * handler.
-     */
-    public void requestP2pSettings(Channel c) {
-        if (c == null) return;
-        c.mAsyncChannel.sendMessage(REQUEST_SETTINGS);
-    }
-
-    /**
      * Request the list of peers. This returns a RESPONSE_PEERS on the source
      * handler.
      */
@@ -365,12 +308,19 @@
     }
 
     /**
-     * Request device connection status. This returns a RESPONSE_CONNECTION_STATUS on
+     * Request device connection info. This returns a RESPONSE_CONNECTION_INFO on
      * the source handler.
      */
-    public void requestConnectionStatus(Channel c) {
+    public void requestConnectionInfo(Channel c) {
         if (c == null) return;
-        c.mAsyncChannel.sendMessage(REQUEST_CONNECTION_STATUS);
+        c.mAsyncChannel.sendMessage(REQUEST_CONNECTION_INFO);
+    }
+
+    /**
+     * Fetch p2p connection status from a RESPONSE_CONNECTION_INFO message
+     */
+    public WifiP2pInfo connectionInfoInResponse(Message msg) {
+        return (WifiP2pInfo) msg.obj;
     }
 
 
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pService.java b/wifi/java/android/net/wifi/p2p/WifiP2pService.java
index 4447971..adf13be 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pService.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pService.java
@@ -93,12 +93,25 @@
     private int mWifiApState = WifiManager.WIFI_AP_STATE_DISABLED;
 
     private P2pStateMachine mP2pStateMachine;
-    private AsyncChannel mReplyChannel = new AsyncChannel();;
+    private AsyncChannel mReplyChannel = new AsyncChannel();
     private AsyncChannel mWifiChannel;
 
-    private static final int GROUP_NEGOTIATION_WAIT_TIME_MS = 60 * 1000;
+    /* Two minutes comes from the wpa_supplicant setting */
+    private static final int GROUP_NEGOTIATION_WAIT_TIME_MS = 120 * 1000;
     private static int mGroupNegotiationTimeoutIndex = 0;
 
+    /**
+     * Delay between restarts upon failure to setup connection with supplicant
+     */
+    private static final int P2P_RESTART_INTERVAL_MSECS = 5000;
+
+    /**
+     * Number of times we attempt to restart p2p
+     */
+    private static final int P2P_RESTART_TRIES = 5;
+
+    private int mP2pRestartCount = 0;
+
     private static final int BASE = Protocol.BASE_WIFI_P2P_SERVICE;
 
     /* Message sent to WifiStateMachine to indicate p2p enable is pending */
@@ -115,14 +128,17 @@
     private final boolean mP2pSupported;
 
     private NetworkInfo mNetworkInfo;
-    private LinkProperties mLinkProperties;
+
+    /* Is chosen as a unique range to avoid conflict with
+       the range defined in Tethering.java */
+    private static final String[] DHCP_RANGE = {"192.168.49.2", "192.168.49.254"};
+    private static final String SERVER_ADDRESS = "192.168.49.1";
 
     public WifiP2pService(Context context) {
         mContext = context;
 
         mInterface = SystemProperties.get("wifi.interface", "wlan0");
         mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_WIFI_P2P, 0, NETWORKTYPE, "");
-        mLinkProperties = new LinkProperties();
 
         mP2pSupported = mContext.getResources().getBoolean(
                 com.android.internal.R.bool.config_wifi_p2p_support);
@@ -205,6 +221,7 @@
         private P2pNotSupportedState mP2pNotSupportedState = new P2pNotSupportedState();
         private P2pDisablingState mP2pDisablingState = new P2pDisablingState();
         private P2pDisabledState mP2pDisabledState = new P2pDisabledState();
+        private WaitForUserActionState mWaitForUserActionState = new WaitForUserActionState();
         private WaitForWifiDisableState mWaitForWifiDisableState = new WaitForWifiDisableState();
         private P2pEnablingState mP2pEnablingState = new P2pEnablingState();
         private P2pEnabledState mP2pEnabledState = new P2pEnabledState();
@@ -216,11 +233,9 @@
         private WifiMonitor mWifiMonitor = new WifiMonitor(this);
 
         private WifiP2pDeviceList mPeers = new WifiP2pDeviceList();
+        private WifiP2pInfo mWifiP2pInfo = new WifiP2pInfo();
         private WifiP2pGroup mGroup;
 
-        // Saved enable request message so the state machine can send an appropriate response
-        private Message mSavedEnableRequestMessage;
-
         // Saved WifiP2pConfig from GO negotiation request
         private WifiP2pConfig mSavedGoNegotiationConfig;
 
@@ -237,7 +252,8 @@
                 addState(mP2pNotSupportedState, mDefaultState);
                 addState(mP2pDisablingState, mDefaultState);
                 addState(mP2pDisabledState, mDefaultState);
-                addState(mWaitForWifiDisableState, mDefaultState);
+                    addState(mWaitForUserActionState, mP2pDisabledState);
+                    addState(mWaitForWifiDisableState, mP2pDisabledState);
                 addState(mP2pEnablingState, mDefaultState);
                 addState(mP2pEnabledState, mDefaultState);
                     addState(mInactiveState, mP2pEnabledState);
@@ -251,27 +267,26 @@
             }
         }
 
-    // TODO: Respond to every p2p request with success/failure
     class DefaultState extends State {
         @Override
         public boolean processMessage(Message message) {
-            if (DBG) Slog.d(TAG, getName() + message.toString());
+            if (DBG) logd(getName() + message.toString());
             switch (message.what) {
                 case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
                     if (message.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
-                        if (DBG) Slog.d(TAG, "Full connection with WifiStateMachine established");
+                        if (DBG) logd("Full connection with WifiStateMachine established");
                         mWifiChannel = (AsyncChannel) message.obj;
                     } else {
-                        Slog.e(TAG, "Full connection failure, error = " + message.arg1);
+                        loge("Full connection failure, error = " + message.arg1);
                         mWifiChannel = null;
                     }
                     break;
 
                 case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
                     if (message.arg1 == AsyncChannel.STATUS_SEND_UNSUCCESSFUL) {
-                        Slog.e(TAG, "Send failed, client connection lost");
+                        loge("Send failed, client connection lost");
                     } else {
-                        Slog.e(TAG, "Client connection lost with reason: " + message.arg1);
+                        loge("Client connection lost with reason: " + message.arg1);
                     }
                     mWifiChannel = null;
                     break;
@@ -286,47 +301,35 @@
                     deferMessage(message);
                     break;
                 case WifiP2pManager.ENABLE_P2P:
-                    mReplyChannel.replyToMessage(message, WifiP2pManager.ENABLE_P2P_FAILED);
+                    replyToMessage(message, WifiP2pManager.ENABLE_P2P_FAILED);
                     break;
                 case WifiP2pManager.DISABLE_P2P:
-                    mReplyChannel.replyToMessage(message, WifiP2pManager.DISABLE_P2P_FAILED);
-                    break;
-                case WifiP2pManager.START_LISTEN_MODE:
-                    mReplyChannel.replyToMessage(message, WifiP2pManager.START_LISTEN_FAILED);
+                    replyToMessage(message, WifiP2pManager.DISABLE_P2P_FAILED);
                     break;
                 case WifiP2pManager.DISCOVER_PEERS:
-                    mReplyChannel.replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_FAILED);
-                    break;
-                case WifiP2pManager.CANCEL_DISCOVER_PEERS:
-                    mReplyChannel.replyToMessage(message,
-                            WifiP2pManager.CANCEL_DISCOVER_PEERS_FAILED);
+                    replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_FAILED);
                     break;
                 case WifiP2pManager.CONNECT:
-                    mReplyChannel.replyToMessage(message, WifiP2pManager.CONNECT_FAILED);
-                    break;
-                case WifiP2pManager.CANCEL_CONNECT:
-                    mReplyChannel.replyToMessage(message, WifiP2pManager.CANCEL_CONNECT_FAILED);
-                    break;
-                case WifiP2pManager.REJECT:
-                    mReplyChannel.replyToMessage(message, WifiP2pManager.REJECT_FAILED);
+                    replyToMessage(message, WifiP2pManager.CONNECT_FAILED);
                     break;
                 case WifiP2pManager.CREATE_GROUP:
-                    mReplyChannel.replyToMessage(message, WifiP2pManager.CREATE_GROUP_FAILED);
+                    replyToMessage(message, WifiP2pManager.CREATE_GROUP_FAILED);
                     break;
                 case WifiP2pManager.REMOVE_GROUP:
-                    mReplyChannel.replyToMessage(message, WifiP2pManager.REMOVE_GROUP_FAILED);
+                    replyToMessage(message, WifiP2pManager.REMOVE_GROUP_FAILED);
                     break;
-                // TODO: fix
-                case WifiP2pManager.REQUEST_SETTINGS:
                 case WifiP2pManager.REQUEST_PEERS:
-                case WifiP2pManager.REQUEST_CONNECTION_STATUS:
+                    replyToMessage(message, WifiP2pManager.RESPONSE_PEERS, mPeers);
+                    break;
+                case WifiP2pManager.REQUEST_CONNECTION_INFO:
+                    replyToMessage(message, WifiP2pManager.RESPONSE_CONNECTION_INFO, mWifiP2pInfo);
                     break;
                 // Ignore
                 case WIFI_DISABLE_USER_ACCEPT:
                 case GROUP_NEGOTIATION_TIMED_OUT:
                     break;
                 default:
-                    Slog.e(TAG, "Unhandled message " + message);
+                    loge("Unhandled message " + message);
                     return NOT_HANDLED;
             }
             return HANDLED;
@@ -339,17 +342,33 @@
             switch (message.what) {
                 // Allow Wi-Fi to proceed
                 case WifiStateMachine.WIFI_ENABLE_PENDING:
-                    mReplyChannel.replyToMessage(message, WIFI_ENABLE_PROCEED);
+                    replyToMessage(message, WIFI_ENABLE_PROCEED);
                     break;
                 case WifiP2pManager.ENABLE_P2P:
-                    mReplyChannel.replyToMessage(message, WifiP2pManager.ENABLE_P2P_FAILED,
+                    replyToMessage(message, WifiP2pManager.ENABLE_P2P_FAILED,
                             WifiP2pManager.P2P_UNSUPPORTED);
                     break;
                 case WifiP2pManager.DISABLE_P2P:
-                    mReplyChannel.replyToMessage(message, WifiP2pManager.DISABLE_P2P_FAILED,
+                    replyToMessage(message, WifiP2pManager.DISABLE_P2P_FAILED,
                             WifiP2pManager.P2P_UNSUPPORTED);
                     break;
-                default:
+                case WifiP2pManager.DISCOVER_PEERS:
+                    replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_FAILED,
+                            WifiP2pManager.P2P_UNSUPPORTED);
+                    break;
+                case WifiP2pManager.CONNECT:
+                    replyToMessage(message, WifiP2pManager.CONNECT_FAILED,
+                            WifiP2pManager.P2P_UNSUPPORTED);
+                    break;
+                case WifiP2pManager.CREATE_GROUP:
+                    replyToMessage(message, WifiP2pManager.CREATE_GROUP_FAILED,
+                            WifiP2pManager.P2P_UNSUPPORTED);
+                    break;
+                case WifiP2pManager.REMOVE_GROUP:
+                    replyToMessage(message, WifiP2pManager.REMOVE_GROUP_FAILED,
+                            WifiP2pManager.P2P_UNSUPPORTED);
+                    break;
+               default:
                     return NOT_HANDLED;
             }
             return HANDLED;
@@ -359,17 +378,27 @@
     class P2pDisablingState extends State {
         @Override
         public void enter() {
-            if (DBG) Slog.d(TAG, getName());
-            transitionTo(mP2pDisabledState);
+            if (DBG) logd(getName());
+            logd("stopping supplicant");
+            if (!WifiNative.stopSupplicant()) {
+                loge("Failed to stop supplicant, issue kill");
+                WifiNative.killSupplicant();
+            }
         }
 
         @Override
         public boolean processMessage(Message message) {
-            if (DBG) Slog.d(TAG, getName() + message.toString());
+            if (DBG) logd(getName() + message.toString());
             switch (message.what) {
                 case WifiMonitor.SUP_DISCONNECTION_EVENT:
+                    logd("Supplicant connection lost");
+                    WifiNative.closeSupplicantConnection();
                     transitionTo(mP2pDisabledState);
                     break;
+                case WifiP2pManager.ENABLE_P2P:
+                case WifiP2pManager.DISABLE_P2P:
+                    deferMessage(message);
+                    break;
                 default:
                     return NOT_HANDLED;
             }
@@ -381,23 +410,22 @@
     class P2pDisabledState extends State {
        @Override
         public void enter() {
-            if (DBG) Slog.d(TAG, getName());
+            if (DBG) logd(getName());
         }
 
         @Override
         public boolean processMessage(Message message) {
-            if (DBG) Slog.d(TAG, getName() + message.toString());
+            if (DBG) logd(getName() + message.toString());
             switch (message.what) {
                 case WifiP2pManager.ENABLE_P2P:
-                    mSavedEnableRequestMessage = Message.obtain(message);
                     OnClickListener listener = new OnClickListener() {
                         @Override
                         public void onClick(DialogInterface dialog, int which) {
                             if (which == DialogInterface.BUTTON_POSITIVE) {
                                 sendMessage(WIFI_DISABLE_USER_ACCEPT);
                             } else {
-                                mReplyChannel.replyToMessage(mSavedEnableRequestMessage,
-                                        WifiP2pManager.ENABLE_P2P_FAILED);
+                                logd("User rejected enabling p2p");
+                                //ignore
                             }
                         }
                     };
@@ -414,17 +442,43 @@
                             .create();
                         dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
                         dialog.show();
+                        transitionTo(mWaitForUserActionState);
                     } else {
                         mWifiChannel.sendMessage(P2P_ENABLE_PENDING);
                         transitionTo(mWaitForWifiDisableState);
                     }
+                    replyToMessage(message, WifiP2pManager.ENABLE_P2P_SUCCEEDED);
                     break;
+                case WifiP2pManager.DISABLE_P2P:
+                    replyToMessage(message, WifiP2pManager.DISABLE_P2P_SUCCEEDED);
+                    break;
+                case WifiStateMachine.WIFI_ENABLE_PENDING:
+                    replyToMessage(message, WIFI_ENABLE_PROCEED);
+                    break;
+                default:
+                    return NOT_HANDLED;
+            }
+            return HANDLED;
+        }
+    }
+
+    class WaitForUserActionState extends State {
+        @Override
+        public void enter() {
+            if (DBG) logd(getName());
+        }
+
+        @Override
+        public boolean processMessage(Message message) {
+            if (DBG) logd(getName() + message.toString());
+            switch (message.what) {
                 case WIFI_DISABLE_USER_ACCEPT:
                     mWifiChannel.sendMessage(P2P_ENABLE_PENDING);
                     transitionTo(mWaitForWifiDisableState);
                     break;
-                case WifiStateMachine.WIFI_ENABLE_PENDING:
-                    mReplyChannel.replyToMessage(message, WIFI_ENABLE_PROCEED);
+                case WifiP2pManager.ENABLE_P2P:
+                case WifiP2pManager.DISABLE_P2P:
+                    deferMessage(message);
                     break;
                 default:
                     return NOT_HANDLED;
@@ -436,31 +490,42 @@
     class WaitForWifiDisableState extends State {
         @Override
         public void enter() {
-            if (DBG) Slog.d(TAG, getName());
+            if (DBG) logd(getName());
         }
 
         @Override
         public boolean processMessage(Message message) {
-            if (DBG) Slog.d(TAG, getName() + message.toString());
+            if (DBG) logd(getName() + message.toString());
             switch (message.what) {
                 case WifiStateMachine.P2P_ENABLE_PROCEED:
                     try {
                         mNwService.wifiFirmwareReload(mInterface, "P2P");
                     } catch (Exception e) {
-                        Slog.e(TAG, "Failed to reload p2p firmware " + e);
+                        loge("Failed to reload p2p firmware " + e);
                         // continue
                     }
+
+                    //A runtime crash can leave the interface up and
+                    //this affects p2p when supplicant starts up.
+                    //Ensure interface is down before a supplicant start.
+                    try {
+                        mNwService.setInterfaceDown(mInterface);
+                    } catch (Exception e) {
+                        if (DBG) Slog.w(TAG, "Unable to bring down wlan interface: " + e);
+                    }
+
                     if (WifiNative.startSupplicant()) {
-                        Slog.d(TAG, "Wi-fi Direct start successful");
                         mWifiMonitor.startMonitoring();
                         transitionTo(mP2pEnablingState);
                     } else {
                         notifyP2pEnableFailure();
-                        mReplyChannel.replyToMessage(mSavedEnableRequestMessage,
-                                WifiP2pManager.ENABLE_P2P_FAILED);
                         transitionTo(mP2pDisabledState);
                     }
                     break;
+                case WifiP2pManager.ENABLE_P2P:
+                case WifiP2pManager.DISABLE_P2P:
+                    deferMessage(message);
+                    break;
                 default:
                     return NOT_HANDLED;
             }
@@ -471,22 +536,32 @@
     class P2pEnablingState extends State {
         @Override
         public void enter() {
-            if (DBG) Slog.d(TAG, getName());
+            if (DBG) logd(getName());
         }
 
         @Override
         public boolean processMessage(Message message) {
-            if (DBG) Slog.d(TAG, getName() + message.toString());
+            if (DBG) logd(getName() + message.toString());
             switch (message.what) {
                 case WifiMonitor.SUP_CONNECTION_EVENT:
-                    mReplyChannel.replyToMessage(mSavedEnableRequestMessage,
-                            WifiP2pManager.ENABLE_P2P_SUCCEEDED);
+                    logd("P2p start successful");
                     transitionTo(mInactiveState);
                     break;
-                case WifiP2pManager.DISABLE_P2P:
-                    //TODO: fix
-                    WifiNative.killSupplicant();
+                case WifiMonitor.SUP_DISCONNECTION_EVENT:
+                    if (++mP2pRestartCount <= P2P_RESTART_TRIES) {
+                        loge("Failed to start p2p, retry");
+                        WifiNative.killSupplicant();
+                        sendMessageDelayed(WifiP2pManager.ENABLE_P2P, P2P_RESTART_INTERVAL_MSECS);
+                    } else {
+                        loge("Failed " + mP2pRestartCount + " times to start p2p, quit ");
+                        mP2pRestartCount = 0;
+                    }
                     transitionTo(mP2pDisabledState);
+                    break;
+                case WifiP2pManager.ENABLE_P2P:
+                case WifiP2pManager.DISABLE_P2P:
+                    deferMessage(message);
+                    break;
                 default:
                     return NOT_HANDLED;
             }
@@ -497,27 +572,32 @@
     class P2pEnabledState extends State {
         @Override
         public void enter() {
-            if (DBG) Slog.d(TAG, getName());
+            if (DBG) logd(getName());
             sendP2pStateChangedBroadcast(true);
             mNetworkInfo.setIsAvailable(true);
+            //Start listening for new connections
+            WifiNative.p2pListen();
         }
 
         @Override
         public boolean processMessage(Message message) {
-            if (DBG) Slog.d(TAG, getName() + message.toString());
+            if (DBG) logd(getName() + message.toString());
             switch (message.what) {
+                case WifiP2pManager.ENABLE_P2P:
+                    replyToMessage(message, WifiP2pManager.ENABLE_P2P_SUCCEEDED);
+                    break;
                 case WifiP2pManager.DISABLE_P2P:
-                    // TODO: use stopSupplicant after control channel fixed
-                    WifiNative.killSupplicant();
+                    if (mPeers.clear()) sendP2pPeersChangedBroadcast();
+                    replyToMessage(message, WifiP2pManager.DISABLE_P2P_SUCCEEDED);
                     transitionTo(mP2pDisablingState);
                     break;
                 case WifiP2pManager.DISCOVER_PEERS:
                     int timeout = message.arg1;
-                    WifiNative.p2pFlush();
-                    WifiNative.p2pFind(timeout);
-                   break;
-                case WifiP2pManager.REQUEST_PEERS:
-                    mReplyChannel.replyToMessage(message, WifiP2pManager.RESPONSE_PEERS, mPeers);
+                    if (WifiNative.p2pFind(timeout)) {
+                        replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_SUCCEEDED);
+                    } else {
+                        replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_FAILED);
+                    }
                     break;
                 case WifiMonitor.P2P_DEVICE_FOUND_EVENT:
                     WifiP2pDevice device = (WifiP2pDevice) message.obj;
@@ -529,23 +609,34 @@
                     if (mPeers.remove(device)) sendP2pPeersChangedBroadcast();
                     break;
                 case WifiP2pManager.CONNECT:
-                    if (DBG) Slog.d(TAG, getName() + " sending connect");
+                    if (DBG) logd(getName() + " sending connect");
                     mSavedConnectConfig = (WifiP2pConfig) message.obj;
-                    String pin = WifiNative.p2pConnect(mSavedConnectConfig);
-                    try {
-                        Integer.parseInt(pin);
-                        notifyWpsPin(pin, mSavedConnectConfig.deviceAddress);
-                    } catch (NumberFormatException ignore) {
-                        // do nothing if p2pConnect did not return a pin
+                    int netId = configuredNetworkId(mSavedConnectConfig.deviceAddress);
+                    if (netId >= 0) {
+                        //TODO: if failure, remove config and do a regular p2pConnect()
+                        WifiNative.p2pReinvoke(netId, mSavedConnectConfig.deviceAddress);
+                    } else {
+                        //TODO: Check if device is a GO and "join"
+                        String pin = WifiNative.p2pConnect(mSavedConnectConfig, false);
+                        try {
+                            Integer.parseInt(pin);
+                            notifyWpsPin(pin, mSavedConnectConfig.deviceAddress);
+                        } catch (NumberFormatException ignore) {
+                            // do nothing if p2pConnect did not return a pin
+                        }
                     }
                     updateDeviceStatus(mSavedConnectConfig.deviceAddress, Status.INVITED);
                     sendP2pPeersChangedBroadcast();
+                    replyToMessage(message, WifiP2pManager.CONNECT_SUCCEEDED);
                     transitionTo(mGroupNegotiationState);
                     break;
-                case WifiP2pManager.REJECT:
-                    if (DBG) Slog.d(TAG, getName() + " sending reject");
-                    WifiNative.p2pReject((String) message.obj);
-                    break;
+                case WifiMonitor.SUP_DISCONNECTION_EVENT:  /* Supplicant died */
+                    loge("Connection lost, restart p2p");
+                    WifiNative.killSupplicant();
+                    WifiNative.closeSupplicantConnection();
+                    if (mPeers.clear()) sendP2pPeersChangedBroadcast();
+                    transitionTo(mP2pDisabledState);
+                    sendMessageDelayed(WifiP2pManager.ENABLE_P2P, P2P_RESTART_INTERVAL_MSECS);
                 default:
                     return NOT_HANDLED;
             }
@@ -561,28 +652,30 @@
 
     class InactiveState extends State {
         @Override public void enter() {
-            if (DBG) Slog.d(TAG, getName());
+            if (DBG) logd(getName());
         }
 
         @Override
         public boolean processMessage(Message message) {
-            if (DBG) Slog.d(TAG, getName() + message.toString());
+            if (DBG) logd(getName() + message.toString());
             switch (message.what) {
                 case WifiMonitor.P2P_GO_NEGOTIATION_REQUEST_EVENT:
                     mSavedGoNegotiationConfig = (WifiP2pConfig) message.obj;
                     notifyP2pGoNegotationRequest(mSavedGoNegotiationConfig);
                     break;
                 case WifiP2pManager.CREATE_GROUP:
-                    WifiNative.p2pGroupAdd();
+                    if (WifiNative.p2pGroupAdd()) {
+                        replyToMessage(message, WifiP2pManager.CREATE_GROUP_SUCCEEDED);
+                    } else {
+                        replyToMessage(message, WifiP2pManager.CREATE_GROUP_FAILED);
+                    }
                     transitionTo(mGroupNegotiationState);
                     break;
                 case WifiMonitor.P2P_INVITATION_RECEIVED_EVENT:
                     WifiP2pGroup group = (WifiP2pGroup) message.obj;
                     notifyP2pInvitationReceived(group);
                     break;
-                case WifiP2pManager.REQUEST_PEERS:
-                    return NOT_HANDLED;
-               default:
+                default:
                     return NOT_HANDLED;
             }
             return HANDLED;
@@ -592,31 +685,32 @@
     class GroupNegotiationState extends State {
         @Override
         public void enter() {
-            if (DBG) Slog.d(TAG, getName());
+            if (DBG) logd(getName());
             sendMessageDelayed(obtainMessage(GROUP_NEGOTIATION_TIMED_OUT,
                     ++mGroupNegotiationTimeoutIndex, 0), GROUP_NEGOTIATION_WAIT_TIME_MS);
         }
 
         @Override
         public boolean processMessage(Message message) {
-            if (DBG) Slog.d(TAG, getName() + message.toString());
+            if (DBG) logd(getName() + message.toString());
             switch (message.what) {
                 // We ignore these right now, since we get a GROUP_STARTED notification
                 // afterwards
                 case WifiMonitor.P2P_GO_NEGOTIATION_SUCCESS_EVENT:
                 case WifiMonitor.P2P_GROUP_FORMATION_SUCCESS_EVENT:
-                    if (DBG) Slog.d(TAG, getName() + " go success");
+                    if (DBG) logd(getName() + " go success");
                     break;
                 case WifiMonitor.P2P_GO_NEGOTIATION_FAILURE_EVENT:
                 case WifiMonitor.P2P_GROUP_FORMATION_FAILURE_EVENT:
-                    if (DBG) Slog.d(TAG, getName() + " go failure");
+                    if (DBG) logd(getName() + " go failure");
                     updateDeviceStatus(mSavedConnectConfig.deviceAddress, Status.FAILED);
                     mSavedConnectConfig = null;
+                    sendP2pPeersChangedBroadcast();
                     transitionTo(mInactiveState);
                     break;
                 case WifiMonitor.P2P_GROUP_STARTED_EVENT:
                     mGroup = (WifiP2pGroup) message.obj;
-                    if (DBG) Slog.d(TAG, getName() + " group started");
+                    if (DBG) logd(getName() + " group started");
                     if (mGroup.isGroupOwner()) {
                         startDhcpServer(mGroup.getInterface());
                     } else {
@@ -629,14 +723,12 @@
                     }
                     transitionTo(mGroupCreatedState);
                     break;
-                case WifiP2pManager.CANCEL_CONNECT:
-                    // TODO: fix
-                    break;
                 case GROUP_NEGOTIATION_TIMED_OUT:
                     if (mGroupNegotiationTimeoutIndex == message.arg1) {
-                        if (DBG) Slog.d(TAG, "Group negotiation timed out");
+                        if (DBG) logd("Group negotiation timed out");
                         updateDeviceStatus(mSavedConnectConfig.deviceAddress, Status.FAILED);
                         mSavedConnectConfig = null;
+                        sendP2pPeersChangedBroadcast();
                         transitionTo(mInactiveState);
                     }
                     break;
@@ -650,17 +742,19 @@
     class GroupCreatedState extends State {
         @Override
         public void enter() {
-            if (DBG) Slog.d(TAG, getName());
+            if (DBG) logd(getName());
             mNetworkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, null, null);
 
+            //DHCP server has already been started if I am a group owner
             if (mGroup.isGroupOwner()) {
+                setWifiP2pInfoOnGroupFormation(SERVER_ADDRESS);
                 sendP2pConnectionChangedBroadcast();
             }
         }
 
         @Override
         public boolean processMessage(Message message) {
-            if (DBG) Slog.d(TAG, getName() + message.toString());
+            if (DBG) logd(getName() + message.toString());
             switch (message.what) {
                 case WifiMonitor.AP_STA_CONNECTED_EVENT:
                     //After a GO setup, STA connected event comes with interface address
@@ -668,7 +762,7 @@
                     String deviceAddress = getDeviceAddress(interfaceAddress);
                     mGroup.addClient(deviceAddress);
                     updateDeviceStatus(deviceAddress, Status.CONNECTED);
-                    if (DBG) Slog.d(TAG, getName() + " ap sta connected");
+                    if (DBG) logd(getName() + " ap sta connected");
                     sendP2pPeersChangedBroadcast();
                     break;
                 case WifiMonitor.AP_STA_DISCONNECTED_EVENT:
@@ -676,40 +770,37 @@
                     deviceAddress = getDeviceAddress(interfaceAddress);
                     updateDeviceStatus(deviceAddress, Status.AVAILABLE);
                     if (mGroup.removeClient(deviceAddress)) {
-                        if (DBG) Slog.d(TAG, "Removed client " + deviceAddress);
-                        if (mGroup.isClientListEmpty()) {
-                            Slog.d(TAG, "Client list empty, killing p2p connection");
-                            sendMessage(WifiP2pManager.REMOVE_GROUP);
-                        } else {
-                            // Just send a notification
-                            sendP2pPeersChangedBroadcast();
-                        }
+                        if (DBG) logd("Removed client " + deviceAddress);
+                        sendP2pPeersChangedBroadcast();
                     } else {
-                        if (DBG) Slog.d(TAG, "Failed to remove client " + deviceAddress);
+                        if (DBG) logd("Failed to remove client " + deviceAddress);
                         for (WifiP2pDevice c : mGroup.getClientList()) {
-                            if (DBG) Slog.d(TAG,"client " + c.deviceAddress);
+                            if (DBG) logd("client " + c.deviceAddress);
                         }
                     }
-                    if (DBG) Slog.e(TAG, getName() + " ap sta disconnected");
+                    if (DBG) loge(getName() + " ap sta disconnected");
                     break;
                 case DhcpStateMachine.CMD_POST_DHCP_ACTION:
                     DhcpInfoInternal dhcpInfo = (DhcpInfoInternal) message.obj;
-                    if (DBG) Slog.d(TAG, "DhcpInfo: " + dhcpInfo);
-                    if (dhcpInfo != null) {
-                        mLinkProperties = dhcpInfo.makeLinkProperties();
-                        mLinkProperties.setInterfaceName(mGroup.getInterface());
+                    if (message.arg1 == DhcpStateMachine.DHCP_SUCCESS &&
+                            dhcpInfo != null) {
+                        if (DBG) logd("DhcpInfo: " + dhcpInfo);
+                        setWifiP2pInfoOnGroupFormation(dhcpInfo.serverAddress);
                         sendP2pConnectionChangedBroadcast();
+                    } else {
+                        WifiNative.p2pGroupRemove(mGroup.getInterface());
                     }
                     break;
-                //disconnect & remove group have same effect when connected
-                case WifiP2pManager.CANCEL_CONNECT:
                 case WifiP2pManager.REMOVE_GROUP:
-                    if (DBG) Slog.e(TAG, getName() + " remove group");
-                    WifiNative.p2pFlush();
-                    WifiNative.p2pGroupRemove(mGroup.getInterface());
+                    if (DBG) loge(getName() + " remove group");
+                    if (WifiNative.p2pGroupRemove(mGroup.getInterface())) {
+                        replyToMessage(message, WifiP2pManager.REMOVE_GROUP_SUCCEEDED);
+                    } else {
+                        replyToMessage(message, WifiP2pManager.REMOVE_GROUP_FAILED);
+                    }
                     break;
                 case WifiMonitor.P2P_GROUP_REMOVED_EVENT:
-                    if (DBG) Slog.e(TAG, getName() + " group removed");
+                    if (DBG) loge(getName() + " group removed");
                     Collection <WifiP2pDevice> devices = mGroup.getClientList();
                     boolean changed = false;
                     for (WifiP2pDevice d : mPeers.getDeviceList()) {
@@ -722,7 +813,7 @@
                     if (mGroup.isGroupOwner()) {
                         stopDhcpServer();
                     } else {
-                        if (DBG) Slog.d(TAG, "stop DHCP client");
+                        if (DBG) logd("stop DHCP client");
                         mDhcpStateMachine.sendMessage(DhcpStateMachine.CMD_STOP_DHCP);
                         mDhcpStateMachine.quit();
                         mDhcpStateMachine = null;
@@ -735,33 +826,30 @@
                 case WifiMonitor.P2P_DEVICE_LOST_EVENT:
                     WifiP2pDevice device = (WifiP2pDevice) message.obj;
                     if (device.equals(mGroup.getOwner())) {
-                        Slog.d(TAG, "Lost the group owner, killing p2p connection");
-                        WifiNative.p2pFlush();
+                        logd("Lost the group owner, killing p2p connection");
                         WifiNative.p2pGroupRemove(mGroup.getInterface());
-                    } else if (mGroup.removeClient(device) && mGroup.isClientListEmpty()) {
-                        Slog.d(TAG, "Client list empty, killing p2p connection");
-                        WifiNative.p2pFlush();
-                        WifiNative.p2pGroupRemove(mGroup.getInterface());
+                    } else {
+                        mGroup.removeClient(device);
                     }
                     return NOT_HANDLED; // Do the regular device lost handling
                 case WifiP2pManager.DISABLE_P2P:
                     sendMessage(WifiP2pManager.REMOVE_GROUP);
                     deferMessage(message);
                     break;
-                case WifiP2pManager.DISCOVER_PEERS:
-                    int timeout = message.arg1;
-                    WifiNative.p2pFind(timeout);
-                    break;
                 case WifiP2pManager.CONNECT:
                     WifiP2pConfig config = (WifiP2pConfig) message.obj;
-                    Slog.d(TAG, "Inviting device : " + config.deviceAddress);
-                    WifiNative.p2pInvite(mGroup, config.deviceAddress);
-                    updateDeviceStatus(config.deviceAddress, Status.INVITED);
-                    sendP2pPeersChangedBroadcast();
+                    logd("Inviting device : " + config.deviceAddress);
+                    if (WifiNative.p2pInvite(mGroup, config.deviceAddress)) {
+                        updateDeviceStatus(config.deviceAddress, Status.INVITED);
+                        sendP2pPeersChangedBroadcast();
+                        replyToMessage(message, WifiP2pManager.CONNECT_SUCCEEDED);
+                    } else {
+                        replyToMessage(message, WifiP2pManager.CONNECT_FAILED);
+                    }
                     // TODO: figure out updating the status to declined when invitation is rejected
                     break;
                 case WifiMonitor.P2P_INVITATION_RESULT_EVENT:
-                    Slog.d(TAG,"===> INVITATION RESULT EVENT : " + message.obj);
+                    logd("===> INVITATION RESULT EVENT : " + message.obj);
                     break;
                 case WifiMonitor.P2P_PROV_DISC_PBC_REQ_EVENT:
                     notifyP2pProvDiscPbcRequest((WifiP2pDevice) message.obj);
@@ -782,7 +870,9 @@
         }
 
         public void exit() {
+            setWifiP2pInfoOnGroupTermination();
             mNetworkInfo.setDetailedState(NetworkInfo.DetailedState.DISCONNECTED, null, null);
+            sendP2pConnectionChangedBroadcast();
         }
     }
 
@@ -806,52 +896,42 @@
     }
 
     private void sendP2pConnectionChangedBroadcast() {
-        if (DBG) Slog.d(TAG, "sending p2p connection changed broadcast");
+        if (DBG) logd("sending p2p connection changed broadcast");
         Intent intent = new Intent(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
                 | Intent.FLAG_RECEIVER_REPLACE_PENDING);
+        intent.putExtra(WifiP2pManager.EXTRA_WIFI_P2P_INFO, new WifiP2pInfo(mWifiP2pInfo));
         intent.putExtra(WifiP2pManager.EXTRA_NETWORK_INFO, new NetworkInfo(mNetworkInfo));
-        intent.putExtra(WifiP2pManager.EXTRA_LINK_PROPERTIES,
-                new LinkProperties (mLinkProperties));
         mContext.sendStickyBroadcast(intent);
     }
 
     private void startDhcpServer(String intf) {
-        /* Is chosen as a unique range to avoid conflict with
-           the range defined in Tethering.java */
-        String[] dhcp_range = {"192.168.49.2", "192.168.49.254"};
-        String serverAddress = "192.168.49.1";
-
-        mLinkProperties.clear();
-        mLinkProperties.setInterfaceName(mGroup.getInterface());
-
         InterfaceConfiguration ifcg = null;
         try {
             ifcg = mNwService.getInterfaceConfig(intf);
             ifcg.addr = new LinkAddress(NetworkUtils.numericToInetAddress(
-                        serverAddress), 24);
+                        SERVER_ADDRESS), 24);
             ifcg.interfaceFlags = "[up]";
             mNwService.setInterfaceConfig(intf, ifcg);
             /* This starts the dnsmasq server */
-            mNwService.startTethering(dhcp_range);
+            mNwService.startTethering(DHCP_RANGE);
         } catch (Exception e) {
-            Slog.e(TAG, "Error configuring interface " + intf + ", :" + e);
+            loge("Error configuring interface " + intf + ", :" + e);
             return;
         }
 
-        mLinkProperties.addDns(NetworkUtils.numericToInetAddress(serverAddress));
-        Slog.d(TAG, "Started Dhcp server on " + intf);
-    }
+        logd("Started Dhcp server on " + intf);
+   }
 
     private void stopDhcpServer() {
         try {
             mNwService.stopTethering();
         } catch (Exception e) {
-            Slog.e(TAG, "Error stopping Dhcp server" + e);
+            loge("Error stopping Dhcp server" + e);
             return;
         }
 
-        Slog.d(TAG, "Stopped Dhcp server");
+        logd("Stopped Dhcp server");
     }
 
     private void notifyP2pEnableFailure() {
@@ -888,7 +968,7 @@
             .setView(textEntryView)
             .setPositiveButton(r.getString(R.string.ok), new OnClickListener() {
                         public void onClick(DialogInterface dialog, int which) {
-                            if (DBG) Slog.d(TAG, getName() + " connect " + pin.getText());
+                            if (DBG) logd(getName() + " connect " + pin.getText());
 
                             if (pin.getVisibility() == View.GONE) {
                                 mSavedGoNegotiationConfig.wpsConfig.setup = Setup.PBC;
@@ -903,10 +983,8 @@
             .setNegativeButton(r.getString(R.string.cancel), new OnClickListener() {
                         @Override
                         public void onClick(DialogInterface dialog, int which) {
-                                if (DBG) Slog.d(TAG, getName() + " reject");
-                                sendMessage(WifiP2pManager.REJECT,
-                                        mSavedGoNegotiationConfig.deviceAddress);
-                                mSavedGoNegotiationConfig = null;
+                            if (DBG) logd(getName() + " ignore connect");
+                            mSavedGoNegotiationConfig = null;
                         }
                     })
             .create();
@@ -935,7 +1013,7 @@
             .setView(textEntryView)
             .setPositiveButton(r.getString(R.string.ok), new OnClickListener() {
                         public void onClick(DialogInterface dialog, int which) {
-                                if (DBG) Slog.d(TAG, getName() + " wps_pbc");
+                                if (DBG) logd(getName() + " wps_pbc");
                                 sendMessage(WifiP2pManager.WPS_PBC);
                         }
                     })
@@ -961,7 +1039,7 @@
             .setView(textEntryView)
             .setPositiveButton(r.getString(R.string.ok), new OnClickListener() {
                     public void onClick(DialogInterface dialog, int which) {
-                        if (DBG) Slog.d(TAG, getName() + " wps_pin");
+                        if (DBG) logd(getName() + " wps_pin");
                         sendMessage(WifiP2pManager.WPS_PIN, pin.getText().toString());
                     }
                     })
@@ -989,8 +1067,7 @@
                         public void onClick(DialogInterface dialog, int which) {
                                 WifiP2pConfig config = new WifiP2pConfig();
                                 config.deviceAddress = mSavedP2pGroup.getOwner().deviceAddress;
-                                config.joinExistingGroup = true;
-                                if (DBG) Slog.d(TAG, getName() + " connect to invited group");
+                                if (DBG) logd(getName() + " connect to invited group");
                                 sendMessage(WifiP2pManager.CONNECT, config);
                                 mSavedP2pGroup = null;
                         }
@@ -1014,6 +1091,23 @@
         }
     }
 
+    //TODO: implement when wpa_supplicant is fixed
+    private int configuredNetworkId(String deviceAddress) {
+        return -1;
+    }
+
+    private void setWifiP2pInfoOnGroupFormation(String serverAddress) {
+        mWifiP2pInfo.groupFormed = true;
+        mWifiP2pInfo.isGroupOwner = mGroup.isGroupOwner();
+        mWifiP2pInfo.groupOwnerAddress = NetworkUtils.numericToInetAddress(serverAddress);
+    }
+
+    private void setWifiP2pInfoOnGroupTermination() {
+        mWifiP2pInfo.groupFormed = false;
+        mWifiP2pInfo.isGroupOwner = false;
+        mWifiP2pInfo.groupOwnerAddress = null;
+    }
+
     private String getDeviceAddress(String interfaceAddress) {
         for (WifiP2pDevice d : mPeers.getDeviceList()) {
             if (interfaceAddress.equals(WifiNative.p2pGetInterfaceAddress(d.deviceAddress))) {
@@ -1023,5 +1117,25 @@
         return null;
     }
 
+    //State machine initiated requests can have replyTo set to null indicating
+    //there are no recepients, we ignore those reply actions
+    private void replyToMessage(Message msg, int what) {
+        if (msg.replyTo == null) return;
+        mReplyChannel.replyToMessage(msg, what);
+    }
+
+    private void replyToMessage(Message msg, int what, Object obj) {
+        if (msg.replyTo == null) return;
+        mReplyChannel.replyToMessage(msg, what, obj);
+    }
+
+    private void logd(String s) {
+        Slog.d(TAG, s);
+    }
+
+    private void loge(String s) {
+        Slog.e(TAG, s);
+    }
+
     }
 }
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pStatus.java b/wifi/java/android/net/wifi/p2p/WifiP2pStatus.java
deleted file mode 100644
index 1c9b76c..0000000
--- a/wifi/java/android/net/wifi/p2p/WifiP2pStatus.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.p2p;
-
-import android.os.Parcelable;
-import android.os.Parcel;
-
-/**
- * A class representing Wi-fi P2p status
- * @hide
- */
-public class WifiP2pStatus implements Parcelable {
-
-    //Comes from the wpa_supplicant
-    enum p2p_status_code {
-        SUCCESS,
-        FAIL_INFO_CURRENTLY_UNAVAILABLE,
-        FAIL_INCOMPATIBLE_PARAMS,
-        FAIL_LIMIT_REACHED,
-        FAIL_INVALID_PARAMS,
-        FAIL_UNABLE_TO_ACCOMMODATE,
-        FAIL_PREV_PROTOCOL_ERROR,
-        FAIL_NO_COMMON_CHANNELS,
-        FAIL_UNKNOWN_GROUP,
-        FAIL_BOTH_GO_INTENT_15,
-        FAIL_INCOMPATIBLE_PROV_METHOD,
-        FAIL_REJECTED_BY_USER
-    };
-
-    public WifiP2pStatus() {
-    }
-
-    //TODO: add support
-    public String toString() {
-        StringBuffer sbuf = new StringBuffer();
-        return sbuf.toString();
-    }
-
-    /** Implement the Parcelable interface {@hide} */
-    public int describeContents() {
-        return 0;
-    }
-
-    /** copy constructor {@hide} */
-    //TODO: implement
-    public WifiP2pStatus(WifiP2pStatus source) {
-        if (source != null) {
-       }
-    }
-
-    /** Implement the Parcelable interface {@hide} */
-    // STOPSHIP: implement
-    public void writeToParcel(Parcel dest, int flags) {
-    }
-
-    /** Implement the Parcelable interface {@hide} */
-    public static final Creator<WifiP2pStatus> CREATOR =
-        new Creator<WifiP2pStatus>() {
-            public WifiP2pStatus createFromParcel(Parcel in) {
-                WifiP2pStatus status = new WifiP2pStatus();
-                return status;
-            }
-
-            public WifiP2pStatus[] newArray(int size) {
-                return new WifiP2pStatus[size];
-            }
-        };
-}