Merge "Import revised translations."
diff --git a/api/current.txt b/api/current.txt
index d009a64..9ad7b4e 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -183,14 +183,14 @@
public static final class R.attr {
ctor public R.attr();
field public static final int absListViewStyle = 16842858; // 0x101006a
- field public static final int accessibilityEventTypes = 16843650; // 0x1010382
- field public static final int accessibilityFeedbackType = 16843652; // 0x1010384
- field public static final int accessibilityFlags = 16843654; // 0x1010386
+ field public static final int accessibilityEventTypes = 16843649; // 0x1010381
+ field public static final int accessibilityFeedbackType = 16843651; // 0x1010383
+ field public static final int accessibilityFlags = 16843653; // 0x1010385
field public static final int accountPreferences = 16843423; // 0x101029f
field public static final int accountType = 16843407; // 0x101028f
field public static final int action = 16842797; // 0x101002d
field public static final int actionBarSize = 16843499; // 0x10102eb
- field public static final int actionBarSplitStyle = 16843676; // 0x101039c
+ field public static final int actionBarSplitStyle = 16843675; // 0x101039b
field public static final int actionBarStyle = 16843470; // 0x10102ce
field public static final int actionBarTabBarStyle = 16843508; // 0x10102f4
field public static final int actionBarTabStyle = 16843507; // 0x10102f3
@@ -206,9 +206,9 @@
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 = 16843648; // 0x1010380
+ field public static final int actionModeSelectAllDrawable = 16843647; // 0x101037f
field public static final int actionOverflowButtonStyle = 16843510; // 0x10102f6
- field public static final int actionProviderClass = 16843678; // 0x101039e
+ field public static final int actionProviderClass = 16843677; // 0x101039d
field public static final int actionViewClass = 16843516; // 0x10102fc
field public static final int activatedBackgroundIndicator = 16843517; // 0x10102fd
field public static final int activityCloseEnterAnimation = 16842938; // 0x10100ba
@@ -220,7 +220,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 = 16843642; // 0x101037a
+ field public static final int alignmentMode = 16843641; // 0x1010379
field public static final int allContactsName = 16843468; // 0x10102cc
field public static final int allowBackup = 16843392; // 0x1010280
field public static final int allowClearUserData = 16842757; // 0x1010005
@@ -254,6 +254,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 = 16843679; // 0x101039f
+ field public static final int backgroundStacked = 16843678; // 0x101039e
field public static final int backupAgent = 16843391; // 0x101027f
field public static final int baseline = 16843548; // 0x101031c
field public static final int baselineAlignBottom = 16843042; // 0x1010122
@@ -262,7 +264,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 = 16843661; // 0x101038d
+ field public static final int bottomChevronDrawable = 16843660; // 0x101038c
field public static final int bottomDark = 16842953; // 0x10100c9
field public static final int bottomLeftRadius = 16843179; // 0x10101ab
field public static final int bottomMedium = 16842958; // 0x10100ce
@@ -281,7 +283,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 = 16843655; // 0x1010387
+ field public static final int canRetrieveWindowContent = 16843654; // 0x1010386
field public static final int candidatesTextStyleSpans = 16843312; // 0x1010230
field public static final deprecated int capitalize = 16843113; // 0x1010169
field public static final int centerBright = 16842956; // 0x10100cc
@@ -314,9 +316,9 @@
field public static final int colorBackgroundCacheHint = 16843435; // 0x10102ab
field public static final int colorForeground = 16842800; // 0x1010030
field public static final int colorForegroundInverse = 16843270; // 0x1010206
- field public static final int columnCount = 16843639; // 0x1010377
+ field public static final int columnCount = 16843638; // 0x1010376
field public static final int columnDelay = 16843215; // 0x10101cf
- field public static final int columnOrderPreserved = 16843640; // 0x1010378
+ field public static final int columnOrderPreserved = 16843639; // 0x1010377
field public static final int columnWidth = 16843031; // 0x1010117
field public static final int compatibleWidthLimitDp = 16843621; // 0x1010365
field public static final int completionHint = 16843122; // 0x1010172
@@ -429,7 +431,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 = 16843667; // 0x1010393
+ field public static final int feedbackCount = 16843666; // 0x1010392
field public static final int fillAfter = 16843197; // 0x10101bd
field public static final int fillBefore = 16843196; // 0x10101bc
field public static final int fillEnabled = 16843343; // 0x101024f
@@ -462,7 +464,6 @@
field public static final int fromXScale = 16843202; // 0x10101c2
field public static final int fromYDelta = 16843208; // 0x10101c8
field public static final int fromYScale = 16843204; // 0x10101c4
- field public static final int fullBackupAgent = 16843635; // 0x1010373
field public static final int fullBright = 16842954; // 0x10100ca
field public static final int fullDark = 16842950; // 0x10100c6
field public static final int functionalTest = 16842787; // 0x1010023
@@ -483,7 +484,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 = 16843657; // 0x1010389
+ field public static final int handleDrawable = 16843656; // 0x1010388
field public static final int handleProfiling = 16842786; // 0x1010022
field public static final int hapticFeedbackEnabled = 16843358; // 0x101025e
field public static final int hardwareAccelerated = 16843475; // 0x10102d3
@@ -492,12 +493,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 = 16843664; // 0x1010390
+ field public static final int hitRadius = 16843663; // 0x101038f
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 = 16843669; // 0x1010395
+ field public static final int horizontalOffset = 16843668; // 0x1010394
field public static final int horizontalScrollViewStyle = 16843603; // 0x1010353
field public static final int horizontalSpacing = 16843028; // 0x1010114
field public static final int host = 16842792; // 0x1010028
@@ -543,7 +544,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 = 16843649; // 0x1010381
+ field public static final int isAuxiliary = 16843648; // 0x1010380
field public static final int isDefault = 16843297; // 0x1010221
field public static final int isIndicator = 16843079; // 0x1010147
field public static final int isModifier = 16843334; // 0x1010246
@@ -597,30 +598,30 @@
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 = 16843645; // 0x101037d
+ field public static final int layout_columnSpan = 16843644; // 0x101037c
field public static final int layout_gravity = 16842931; // 0x10100b3
field public static final int layout_height = 16842997; // 0x10100f5
- field public static final int layout_heightSpec = 16843647; // 0x101037f
+ field public static final int layout_heightSpec = 16843646; // 0x101037e
field public static final int layout_margin = 16842998; // 0x10100f6
field public static final int layout_marginBottom = 16843002; // 0x10100fa
- field public static final int layout_marginEnd = 16843675; // 0x101039b
+ field public static final int layout_marginEnd = 16843674; // 0x101039a
field public static final int layout_marginLeft = 16842999; // 0x10100f7
field public static final int layout_marginRight = 16843001; // 0x10100f9
- field public static final int layout_marginStart = 16843674; // 0x101039a
+ field public static final int layout_marginStart = 16843673; // 0x1010399
field public static final int layout_marginTop = 16843000; // 0x10100f8
- field public static final int layout_row = 16843643; // 0x101037b
- field public static final int layout_rowSpan = 16843644; // 0x101037c
+ field public static final int layout_row = 16843642; // 0x101037a
+ field public static final int layout_rowSpan = 16843643; // 0x101037b
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
field public static final int layout_toRightOf = 16843139; // 0x1010183
field public static final int layout_weight = 16843137; // 0x1010181
field public static final int layout_width = 16842996; // 0x10100f4
- field public static final int layout_widthSpec = 16843646; // 0x101037e
+ field public static final int layout_widthSpec = 16843645; // 0x101037d
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 = 16843658; // 0x101038a
+ field public static final int leftChevronDrawable = 16843657; // 0x1010389
field public static final int lineSpacingExtra = 16843287; // 0x1010217
field public static final int lineSpacingMultiplier = 16843288; // 0x1010218
field public static final int lines = 16843092; // 0x1010154
@@ -632,8 +633,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 = 16843670; // 0x1010396
- field public static final int listPreferredItemHeightSmall = 16843671; // 0x1010397
+ field public static final int listPreferredItemHeightLarge = 16843669; // 0x1010395
+ field public static final int listPreferredItemHeightSmall = 16843670; // 0x1010396
field public static final int listSelector = 16843003; // 0x10100fb
field public static final int listSeparatorTextViewStyle = 16843272; // 0x1010208
field public static final int listViewStyle = 16842868; // 0x1010074
@@ -679,7 +680,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 = 16843653; // 0x1010385
+ field public static final int notificationTimeout = 16843652; // 0x1010384
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
@@ -693,17 +694,17 @@
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 = 16843663; // 0x101038f
+ field public static final int outerRadius = 16843662; // 0x101038e
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 = 16843651; // 0x1010383
+ field public static final int packageNames = 16843650; // 0x1010382
field public static final int padding = 16842965; // 0x10100d5
field public static final int paddingBottom = 16842969; // 0x10100d9
- field public static final int paddingEnd = 16843673; // 0x1010399
+ field public static final int paddingEnd = 16843672; // 0x1010398
field public static final int paddingLeft = 16842966; // 0x10100d6
field public static final int paddingRight = 16842968; // 0x10100d8
- field public static final int paddingStart = 16843672; // 0x1010398
+ field public static final int paddingStart = 16843671; // 0x1010397
field public static final int paddingTop = 16842967; // 0x10100d7
field public static final int panelBackground = 16842846; // 0x101005e
field public static final int panelColorBackground = 16842849; // 0x1010061
@@ -784,17 +785,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 = 16843659; // 0x101038b
+ field public static final int rightChevronDrawable = 16843658; // 0x101038a
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 = 16843637; // 0x1010375
+ field public static final int rowCount = 16843636; // 0x1010374
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 = 16843638; // 0x1010376
+ field public static final int rowOrderPreserved = 16843637; // 0x1010375
field public static final int saveEnabled = 16842983; // 0x10100e7
field public static final int scaleGravity = 16843262; // 0x10101fe
field public static final int scaleHeight = 16843261; // 0x10101fd
@@ -860,7 +861,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 = 16843666; // 0x1010392
+ field public static final int snapMargin = 16843665; // 0x1010391
field public static final int soundEffectsEnabled = 16843285; // 0x1010215
field public static final int spacing = 16843027; // 0x1010113
field public static final int spinnerDropDownItemStyle = 16842887; // 0x1010087
@@ -908,7 +909,7 @@
field public static final int subtitleTextStyle = 16843513; // 0x10102f9
field public static final int suggestActionMsg = 16843228; // 0x10101dc
field public static final int suggestActionMsgColumn = 16843229; // 0x10101dd
- field public static final int suggestionsEnabled = 16843636; // 0x1010374
+ field public static final int suggestionsEnabled = 16843635; // 0x1010373
field public static final int summary = 16843241; // 0x10101e9
field public static final int summaryColumn = 16843426; // 0x10102a2
field public static final int summaryOff = 16843248; // 0x10101f0
@@ -925,7 +926,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 = 16843656; // 0x1010388
+ field public static final int targetDrawables = 16843655; // 0x1010387
field public static final int targetPackage = 16842785; // 0x1010021
field public static final int targetSdkVersion = 16843376; // 0x1010270
field public static final int taskAffinity = 16842770; // 0x1010012
@@ -976,7 +977,7 @@
field public static final int textColorTertiary = 16843282; // 0x1010212
field public static final int textColorTertiaryInverse = 16843283; // 0x1010213
field public static final int textCursorDrawable = 16843618; // 0x1010362
- field public static final int textDirection = 16843677; // 0x101039d
+ field public static final int textDirection = 16843676; // 0x101039c
field public static final int textEditNoPasteWindowLayout = 16843541; // 0x1010315
field public static final int textEditPasteWindowLayout = 16843540; // 0x1010314
field public static final int textEditSideNoPasteWindowLayout = 16843615; // 0x101035f
@@ -1016,7 +1017,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 = 16843660; // 0x101038c
+ field public static final int topChevronDrawable = 16843659; // 0x101038b
field public static final int topDark = 16842951; // 0x10100c7
field public static final int topLeftRadius = 16843177; // 0x10101a9
field public static final int topOffset = 16843352; // 0x1010258
@@ -1032,7 +1033,7 @@
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 = 16843641; // 0x1010379
+ field public static final int useDefaultMargins = 16843640; // 0x1010378
field public static final int useIntrinsicSizeAsMinimum = 16843536; // 0x1010310
field public static final int useLevel = 16843167; // 0x101019f
field public static final int userVisible = 16843409; // 0x1010291
@@ -1046,10 +1047,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 = 16843668; // 0x1010394
+ field public static final int verticalOffset = 16843667; // 0x1010393
field public static final int verticalScrollbarPosition = 16843572; // 0x1010334
field public static final int verticalSpacing = 16843029; // 0x1010115
- field public static final int vibrationDuration = 16843665; // 0x1010391
+ field public static final int vibrationDuration = 16843664; // 0x1010390
field public static final int visibility = 16842972; // 0x10100dc
field public static final int visible = 16843156; // 0x1010194
field public static final int vmSafeMode = 16843448; // 0x10102b8
@@ -1066,7 +1067,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 = 16843662; // 0x101038e
+ field public static final int waveDrawable = 16843661; // 0x101038d
field public static final int webTextViewStyle = 16843449; // 0x10102b9
field public static final int webViewStyle = 16842885; // 0x1010085
field public static final int weekDayTextAppearance = 16843592; // 0x1010348
@@ -1512,9 +1513,13 @@
field public static final int TextAppearance_Holo_Small_Inverse = 16974082; // 0x1030102
field public static final int TextAppearance_Holo_Widget = 16974085; // 0x1030105
field public static final int TextAppearance_Holo_Widget_ActionBar_Subtitle = 16974099; // 0x1030113
+ field public static final int TextAppearance_Holo_Widget_ActionBar_Subtitle_Inverse = 16974110; // 0x103011e
field public static final int TextAppearance_Holo_Widget_ActionBar_Title = 16974098; // 0x1030112
+ field public static final int TextAppearance_Holo_Widget_ActionBar_Title_Inverse = 16974109; // 0x103011d
field public static final int TextAppearance_Holo_Widget_ActionMode_Subtitle = 16974101; // 0x1030115
+ field public static final int TextAppearance_Holo_Widget_ActionMode_Subtitle_Inverse = 16974112; // 0x1030120
field public static final int TextAppearance_Holo_Widget_ActionMode_Title = 16974100; // 0x1030114
+ field public static final int TextAppearance_Holo_Widget_ActionMode_Title_Inverse = 16974111; // 0x103011f
field public static final int TextAppearance_Holo_Widget_Button = 16974086; // 0x1030106
field public static final int TextAppearance_Holo_Widget_DropDownHint = 16974091; // 0x103010b
field public static final int TextAppearance_Holo_Widget_DropDownItem = 16974092; // 0x103010c
@@ -1577,10 +1582,16 @@
field public static final int Theme_Holo_Light_NoActionBar = 16974064; // 0x10300f0
field public static final int Theme_Holo_Light_NoActionBar_Fullscreen = 16974065; // 0x10300f1
field public static final int Theme_Holo_Light_Panel = 16973948; // 0x103007c
+ field public static final int Theme_Holo_Light_SolidActionBar = 16974121; // 0x1030129
+ field public static final int Theme_Holo_Light_SolidActionBar_Inverse = 16974122; // 0x103012a
+ field public static final int Theme_Holo_Light_SolidActionBar_Inverse_SplitActionBarWhenNarrow = 16974125; // 0x103012d
+ field public static final int Theme_Holo_Light_SolidActionBar_SplitActionBarWhenNarrow = 16974124; // 0x103012c
field public static final int Theme_Holo_Light_SplitActionBarWhenNarrow = 16974106; // 0x103011a
field public static final int Theme_Holo_NoActionBar = 16973932; // 0x103006c
field public static final int Theme_Holo_NoActionBar_Fullscreen = 16973933; // 0x103006d
field public static final int Theme_Holo_Panel = 16973947; // 0x103007b
+ field public static final int Theme_Holo_SolidActionBar = 16974120; // 0x1030128
+ field public static final int Theme_Holo_SolidActionBar_SplitActionBarWhenNarrow = 16974123; // 0x103012b
field public static final int Theme_Holo_SplitActionBarWhenNarrow = 16974105; // 0x1030119
field public static final int Theme_Holo_Wallpaper = 16973949; // 0x103007d
field public static final int Theme_Holo_Wallpaper_NoTitleBar = 16973950; // 0x103007e
@@ -1632,6 +1643,7 @@
field public static final int Widget_GridView = 16973874; // 0x1030032
field public static final int Widget_Holo = 16973962; // 0x103008a
field public static final int Widget_Holo_ActionBar = 16974004; // 0x10300b4
+ field public static final int Widget_Holo_ActionBar_Solid = 16974113; // 0x1030121
field public static final int Widget_Holo_ActionBar_TabBar = 16974071; // 0x10300f7
field public static final int Widget_Holo_ActionBar_TabText = 16974070; // 0x10300f6
field public static final int Widget_Holo_ActionBar_TabView = 16974069; // 0x10300f5
@@ -1661,13 +1673,19 @@
field public static final int Widget_Holo_ImageButton = 16973974; // 0x1030096
field public static final int Widget_Holo_Light = 16974005; // 0x10300b5
field public static final int Widget_Holo_Light_ActionBar = 16974049; // 0x10300e1
+ field public static final int Widget_Holo_Light_ActionBar_Solid = 16974114; // 0x1030122
+ field public static final int Widget_Holo_Light_ActionBar_Solid_Inverse = 16974115; // 0x1030123
field public static final int Widget_Holo_Light_ActionBar_TabBar = 16974074; // 0x10300fa
+ field public static final int Widget_Holo_Light_ActionBar_TabBar_Inverse = 16974116; // 0x1030124
field public static final int Widget_Holo_Light_ActionBar_TabText = 16974073; // 0x10300f9
+ field public static final int Widget_Holo_Light_ActionBar_TabText_Inverse = 16974118; // 0x1030126
field public static final int Widget_Holo_Light_ActionBar_TabView = 16974072; // 0x10300f8
+ field public static final int Widget_Holo_Light_ActionBar_TabView_Inverse = 16974117; // 0x1030125
field public static final int Widget_Holo_Light_ActionButton = 16974045; // 0x10300dd
field public static final int Widget_Holo_Light_ActionButton_CloseMode = 16974048; // 0x10300e0
field public static final int Widget_Holo_Light_ActionButton_Overflow = 16974046; // 0x10300de
field public static final int Widget_Holo_Light_ActionMode = 16974047; // 0x10300df
+ field public static final int Widget_Holo_Light_ActionMode_Inverse = 16974119; // 0x1030127
field public static final int Widget_Holo_Light_AutoCompleteTextView = 16974011; // 0x10300bb
field public static final int Widget_Holo_Light_Button = 16974006; // 0x10300b6
field public static final int Widget_Holo_Light_Button_Borderless_Small = 16974108; // 0x103011c
@@ -3737,7 +3755,11 @@
method public abstract void onBackup(android.os.ParcelFileDescriptor, android.app.backup.BackupDataOutput, android.os.ParcelFileDescriptor) throws java.io.IOException;
method public void onCreate();
method public void onDestroy();
+ method public void onFullBackup(android.app.backup.FullBackupDataOutput) throws java.io.IOException;
method public abstract void onRestore(android.app.backup.BackupDataInput, int, android.os.ParcelFileDescriptor) throws java.io.IOException;
+ method public void onRestoreFile(android.os.ParcelFileDescriptor, long, java.io.File, int, long, long) throws java.io.IOException;
+ field public static final int TYPE_DIRECTORY = 2; // 0x2
+ field public static final int TYPE_FILE = 1; // 0x1
}
public class BackupAgentHelper extends android.app.backup.BackupAgent {
@@ -3789,6 +3811,9 @@
method public void writeNewStateDescription(android.os.ParcelFileDescriptor);
}
+ public class FullBackupDataOutput {
+ }
+
public abstract class RestoreObserver {
ctor public RestoreObserver();
method public void onUpdate(int, java.lang.String);
@@ -17509,8 +17534,12 @@
public final class KeyChain {
ctor public KeyChain();
method public static void choosePrivateKeyAlias(android.app.Activity, android.security.KeyChainAliasCallback, java.lang.String[], java.security.Principal[], java.lang.String, int, java.lang.String);
+ method public static android.content.Intent createInstallIntent();
method public static java.security.cert.X509Certificate[] getCertificateChain(android.content.Context, java.lang.String) throws java.lang.InterruptedException, android.security.KeyChainException;
method public static java.security.PrivateKey getPrivateKey(android.content.Context, java.lang.String) throws java.lang.InterruptedException, android.security.KeyChainException;
+ field public static final java.lang.String EXTRA_CERTIFICATE = "CERT";
+ field public static final java.lang.String EXTRA_NAME = "name";
+ field public static final java.lang.String EXTRA_PKCS12 = "PKCS12";
}
public abstract interface KeyChainAliasCallback {
diff --git a/cmds/dumpstate/dumpstate.c b/cmds/dumpstate/dumpstate.c
index 21bb62e..42c35af 100644
--- a/cmds/dumpstate/dumpstate.c
+++ b/cmds/dumpstate/dumpstate.c
@@ -47,9 +47,11 @@
char build[PROPERTY_VALUE_MAX], fingerprint[PROPERTY_VALUE_MAX];
char radio[PROPERTY_VALUE_MAX], bootloader[PROPERTY_VALUE_MAX];
char network[PROPERTY_VALUE_MAX], date[80];
+ char build_type[PROPERTY_VALUE_MAX];
property_get("ro.build.display.id", build, "(unknown)");
property_get("ro.build.fingerprint", fingerprint, "(unknown)");
+ property_get("ro.build.type", build_type, "(unknown)");
property_get("ro.baseband", radio, "(unknown)");
property_get("ro.bootloader", bootloader, "(unknown)");
property_get("gsm.operator.alpha", network, "(unknown)");
@@ -136,9 +138,17 @@
#ifdef BROKEN_VRIL_IS_FIXED_B_4442803
char ril_dumpstate_timeout[PROPERTY_VALUE_MAX] = {0};
property_get("ril.dumpstate.timeout", ril_dumpstate_timeout, "30");
- if (strlen(ril_dumpstate_timeout) > 0) {
- run_command("DUMP VENDOR RIL LOGS", atoi(ril_dumpstate_timeout),
- "su", "root", "vril-dump", NULL);
+ if (strnlen(ril_dumpstate_timeout, PROPERTY_VALUE_MAX - 1) > 0) {
+ if (0 == strncmp(build_type, "user", PROPERTY_VALUE_MAX - 1)) {
+ // su does not exist on user builds, so try running without it.
+ // This way any implementations of vril-dump that do not require
+ // root can run on user builds.
+ run_command("DUMP VENDOR RIL LOGS", atoi(ril_dumpstate_timeout),
+ "vril-dump", NULL);
+ } else {
+ run_command("DUMP VENDOR RIL LOGS", atoi(ril_dumpstate_timeout),
+ "su", "root", "vril-dump", NULL);
+ }
}
#endif
@@ -275,7 +285,7 @@
if (getuid() == 0) {
/* switch to non-root user and group */
- gid_t groups[] = { AID_LOG, AID_SDCARD_RW, AID_MOUNT };
+ gid_t groups[] = { AID_LOG, AID_SDCARD_RW, AID_MOUNT, AID_INET };
if (setgroups(sizeof(groups)/sizeof(groups[0]), groups) != 0) {
LOGE("Unable to setgroups, aborting: %s\n", strerror(errno));
return -1;
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 1ec7a96..eee14fb 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -2013,15 +2013,10 @@
BackupAgent agent = null;
String classname = data.appInfo.backupAgentName;
- if (data.backupMode == IApplicationThread.BACKUP_MODE_FULL
- || data.backupMode == IApplicationThread.BACKUP_MODE_RESTORE_FULL) {
+ // full backup operation but no app-supplied agent? use the default implementation
+ if (classname == null && (data.backupMode == IApplicationThread.BACKUP_MODE_FULL
+ || data.backupMode == IApplicationThread.BACKUP_MODE_RESTORE_FULL)) {
classname = "android.app.backup.FullBackupAgent";
- if ((data.appInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
- // system packages can supply their own full-backup agent
- if (data.appInfo.fullBackupAgentName != null) {
- classname = data.appInfo.fullBackupAgentName;
- }
- }
}
try {
diff --git a/core/java/android/app/IBackupAgent.aidl b/core/java/android/app/IBackupAgent.aidl
index 8af78fa..087f83c 100644
--- a/core/java/android/app/IBackupAgent.aidl
+++ b/core/java/android/app/IBackupAgent.aidl
@@ -51,7 +51,6 @@
void doBackup(in ParcelFileDescriptor oldState,
in ParcelFileDescriptor data,
in ParcelFileDescriptor newState,
- boolean storeApk,
int token, IBackupManager callbackBinder);
/**
@@ -81,6 +80,25 @@
in ParcelFileDescriptor newState, int token, IBackupManager callbackBinder);
/**
+ * Perform a "full" backup to the given file descriptor. The output file is presumed
+ * to be a socket or other non-seekable, write-only data sink. When this method is
+ * called, the app should write all of its files to the output.
+ *
+ * @param data Write-only file to receive the backed-up file content stream.
+ * The data must be formatted correctly for the resulting archive to be
+ * legitimate, so that will be tightly controlled by the available API.
+ *
+ * @param token Opaque token identifying this transaction. This must
+ * be echoed back to the backup service binder once the agent is
+ * finished restoring the application based on the restore data
+ * contents.
+ *
+ * @param callbackBinder Binder on which to indicate operation completion,
+ * passed here as a convenience to the agent.
+ */
+ void doFullBackup(in ParcelFileDescriptor data, int token, IBackupManager callbackBinder);
+
+ /**
* Restore a single "file" to the application. The file was typically obtained from
* a full-backup dataset. The agent reads 'size' bytes of file content
* from the provided file descriptor.
diff --git a/core/java/android/app/backup/BackupAgent.java b/core/java/android/app/backup/BackupAgent.java
index 63f3258..dce0a97 100644
--- a/core/java/android/app/backup/BackupAgent.java
+++ b/core/java/android/app/backup/BackupAgent.java
@@ -20,13 +20,22 @@
import android.app.backup.IBackupManager;
import android.content.Context;
import android.content.ContextWrapper;
+import android.content.pm.ApplicationInfo;
import android.os.Binder;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.util.Log;
+import java.io.File;
import java.io.IOException;
+import java.util.HashSet;
+import java.util.LinkedList;
+
+import libcore.io.ErrnoException;
+import libcore.io.Libcore;
+import libcore.io.OsConstants;
+import libcore.io.StructStat;
/**
* Provides the central interface between an
@@ -87,6 +96,24 @@
private static final String TAG = "BackupAgent";
private static final boolean DEBUG = true;
+ /** @hide */
+ public static final int TYPE_EOF = 0;
+
+ /**
+ * During a full restore, indicates that the file system object being restored
+ * is an ordinary file.
+ */
+ public static final int TYPE_FILE = 1;
+
+ /**
+ * During a full restore, indicates that the file system object being restored
+ * is a directory.
+ */
+ public static final int TYPE_DIRECTORY = 2;
+
+ /** @hide */
+ public static final int TYPE_SYMLINK = 3;
+
public BackupAgent() {
super(null);
}
@@ -179,18 +206,240 @@
throws IOException;
/**
- * @hide
+ * The default implementation backs up the entirety of the application's "owned"
+ * file system trees to the output.
*/
- public void onRestoreFile(ParcelFileDescriptor data, long size,
- int type, String domain, String path, long mode, long mtime)
- throws IOException {
- // empty stub implementation
+ public void onFullBackup(FullBackupDataOutput data) throws IOException {
+ ApplicationInfo appInfo = getApplicationInfo();
+
+ String rootDir = new File(appInfo.dataDir).getAbsolutePath();
+ String filesDir = getFilesDir().getAbsolutePath();
+ String databaseDir = getDatabasePath("foo").getParentFile().getAbsolutePath();
+ String sharedPrefsDir = getSharedPrefsFile("foo").getParentFile().getAbsolutePath();
+ String cacheDir = getCacheDir().getAbsolutePath();
+ String libDir = (appInfo.nativeLibraryDir != null)
+ ? new File(appInfo.nativeLibraryDir).getAbsolutePath()
+ : null;
+
+ // Filters, the scan queue, and the set of resulting entities
+ HashSet<String> filterSet = new HashSet<String>();
+ String packageName = getPackageName();
+
+ // Okay, start with the app's root tree, but exclude all of the canonical subdirs
+ if (libDir != null) {
+ filterSet.add(libDir);
+ }
+ filterSet.add(cacheDir);
+ filterSet.add(databaseDir);
+ filterSet.add(sharedPrefsDir);
+ filterSet.add(filesDir);
+ fullBackupFileTree(packageName, FullBackup.ROOT_TREE_TOKEN, rootDir, filterSet, data);
+
+ // Now do the same for the files dir, db dir, and shared prefs dir
+ filterSet.add(rootDir);
+ filterSet.remove(filesDir);
+ fullBackupFileTree(packageName, FullBackup.DATA_TREE_TOKEN, filesDir, filterSet, data);
+
+ filterSet.add(filesDir);
+ filterSet.remove(databaseDir);
+ fullBackupFileTree(packageName, FullBackup.DATABASE_TREE_TOKEN, databaseDir, filterSet, data);
+
+ filterSet.add(databaseDir);
+ filterSet.remove(sharedPrefsDir);
+ fullBackupFileTree(packageName, FullBackup.SHAREDPREFS_TREE_TOKEN, sharedPrefsDir, filterSet, data);
}
/**
- * Package-private, used only for dispatching an extra step during full backup
+ * Write an entire file as part of a full-backup operation. The file's contents
+ * will be delivered to the backup destination along with the metadata necessary
+ * to place it with the proper location and permissions on the device where the
+ * data is restored.
+ * @hide
+ *
+ * @param context The BackupAgent that is calling this method. It is an error to
+ * call it from something other than a running BackupAgent instance.
+ * @param file The file to be backed up. The file must exist and be readable by
+ * the caller.
+ * @param output The destination to which the backed-up file data will be sent.
*/
- void onSaveApk(BackupDataOutput data) {
+ public final void fullBackupFile(File file, FullBackupDataOutput output) {
+ // Look up where all of our various well-defined dir trees live on this device
+ String mainDir;
+ String filesDir;
+ String dbDir;
+ String spDir;
+ String cacheDir;
+ String libDir;
+
+ ApplicationInfo appInfo = getApplicationInfo();
+
+ mainDir = new File(appInfo.dataDir).getAbsolutePath();
+ filesDir = getFilesDir().getAbsolutePath();
+ dbDir = getDatabasePath("foo").getParentFile().getAbsolutePath();
+ spDir = getSharedPrefsFile("foo").getParentFile().getAbsolutePath();
+ cacheDir = getCacheDir().getAbsolutePath();
+ libDir = (appInfo.nativeLibraryDir == null) ? null
+ : new File(appInfo.nativeLibraryDir).getAbsolutePath();
+
+ // Now figure out which well-defined tree the file is placed in, working from
+ // most to least specific. We also specifically exclude the lib and cache dirs.
+ String filePath = file.getAbsolutePath();
+
+ if (filePath.startsWith(cacheDir) || filePath.startsWith(libDir)) {
+ Log.w(TAG, "lib and cache files are not backed up");
+ return;
+ }
+
+ final String domain;
+ String rootpath = null;
+ if (filePath.startsWith(dbDir)) {
+ domain = FullBackup.DATABASE_TREE_TOKEN;
+ rootpath = dbDir;
+ } else if (filePath.startsWith(spDir)) {
+ domain = FullBackup.SHAREDPREFS_TREE_TOKEN;
+ rootpath = spDir;
+ } else if (filePath.startsWith(filesDir)) {
+ domain = FullBackup.DATA_TREE_TOKEN;
+ rootpath = filesDir;
+ } else if (filePath.startsWith(mainDir)) {
+ domain = FullBackup.ROOT_TREE_TOKEN;
+ rootpath = mainDir;
+ } else {
+ Log.w(TAG, "File " + filePath + " is in an unsupported location; skipping");
+ return;
+ }
+
+ // And now that we know where it lives, semantically, back it up appropriately
+ Log.i(TAG, "backupFile() of " + filePath + " => domain=" + domain
+ + " rootpath=" + rootpath);
+ FullBackup.backupToTar(getPackageName(), domain, null, rootpath, filePath,
+ output.getData());
+ }
+
+ /**
+ * Scan the dir tree (if it actually exists) and process each entry we find. If the
+ * 'excludes' parameter is non-null, it is consulted each time a new file system entity
+ * is visited to see whether that entity (and its subtree, if appropriate) should be
+ * omitted from the backup process.
+ *
+ * @hide
+ */
+ protected final void fullBackupFileTree(String packageName, String domain, String rootPath,
+ HashSet<String> excludes, FullBackupDataOutput output) {
+ File rootFile = new File(rootPath);
+ if (rootFile.exists()) {
+ LinkedList<File> scanQueue = new LinkedList<File>();
+ scanQueue.add(rootFile);
+
+ while (scanQueue.size() > 0) {
+ File file = scanQueue.remove(0);
+ String filePath = file.getAbsolutePath();
+
+ // prune this subtree?
+ if (excludes != null && excludes.contains(filePath)) {
+ continue;
+ }
+
+ // If it's a directory, enqueue its contents for scanning.
+ try {
+ StructStat stat = Libcore.os.lstat(filePath);
+ if (OsConstants.S_ISLNK(stat.st_mode)) {
+ if (DEBUG) Log.i(TAG, "Symlink (skipping)!: " + file);
+ continue;
+ } else if (OsConstants.S_ISDIR(stat.st_mode)) {
+ File[] contents = file.listFiles();
+ if (contents != null) {
+ for (File entry : contents) {
+ scanQueue.add(0, entry);
+ }
+ }
+ }
+ } catch (ErrnoException e) {
+ if (DEBUG) Log.w(TAG, "Error scanning file " + file + " : " + e);
+ continue;
+ }
+
+ // Finally, back this file up before proceeding
+ FullBackup.backupToTar(packageName, domain, null, rootPath, filePath,
+ output.getData());
+ }
+ }
+ }
+
+ /**
+ * Handle the data delivered via the given file descriptor during a full restore
+ * operation. The agent is given the path to the file's original location as well
+ * as its size and metadata.
+ * <p>
+ * The file descriptor can only be read for {@code size} bytes; attempting to read
+ * more data has undefined behavior.
+ * <p>
+ * The default implementation creates the destination file/directory and populates it
+ * with the data from the file descriptor, then sets the file's access mode and
+ * modification time to match the restore arguments.
+ *
+ * @param data A read-only file descriptor from which the agent can read {@code size}
+ * bytes of file data.
+ * @param size The number of bytes of file content to be restored to the given
+ * destination. If the file system object being restored is a directory, {@code size}
+ * will be zero.
+ * @param destination The File on disk to be restored with the given data.
+ * @param type The kind of file system object being restored. This will be either
+ * {@link BackupAgent#TYPE_FILE} or {@link BackupAgent#TYPE_DIRECTORY}.
+ * @param mode The access mode to be assigned to the destination after its data is
+ * written. This is in the standard format used by {@code chmod()}.
+ * @param mtime The modification time of the file when it was backed up, suitable to
+ * be assigned to the file after its data is written.
+ * @throws IOException
+ */
+ public void onRestoreFile(ParcelFileDescriptor data, long size,
+ File destination, int type, long mode, long mtime)
+ throws IOException {
+ FullBackup.restoreFile(data, size, type, mode, mtime, destination);
+ }
+
+ /**
+ * Only specialized platform agents should overload this entry point to support
+ * restores to crazy non-app locations.
+ * @hide
+ */
+ protected void onRestoreFile(ParcelFileDescriptor data, long size,
+ int type, String domain, String path, long mode, long mtime)
+ throws IOException {
+ String basePath = null;
+
+ if (DEBUG) Log.d(TAG, "onRestoreFile() size=" + size + " type=" + type
+ + " domain=" + domain + " relpath=" + path + " mode=" + mode
+ + " mtime=" + mtime);
+
+ // Parse out the semantic domains into the correct physical location
+ if (domain.equals(FullBackup.DATA_TREE_TOKEN)) {
+ basePath = getFilesDir().getAbsolutePath();
+ } else if (domain.equals(FullBackup.DATABASE_TREE_TOKEN)) {
+ basePath = getDatabasePath("foo").getParentFile().getAbsolutePath();
+ } else if (domain.equals(FullBackup.ROOT_TREE_TOKEN)) {
+ basePath = new File(getApplicationInfo().dataDir).getAbsolutePath();
+ } else if (domain.equals(FullBackup.SHAREDPREFS_TREE_TOKEN)) {
+ basePath = getSharedPrefsFile("foo").getParentFile().getAbsolutePath();
+ } else if (domain.equals(FullBackup.CACHE_TREE_TOKEN)) {
+ basePath = getCacheDir().getAbsolutePath();
+ } else {
+ // Not a supported location
+ Log.i(TAG, "Data restored from non-app domain " + domain + ", ignoring");
+ }
+
+ // Now that we've figured out where the data goes, send it on its way
+ if (basePath != null) {
+ File outFile = new File(basePath, path);
+ if (DEBUG) Log.i(TAG, "[" + domain + " : " + path + "] mapped to " + outFile.getPath());
+ onRestoreFile(data, size, outFile, type, mode, mtime);
+ } else {
+ // Not a supported output location? We need to consume the data
+ // anyway, so just use the default "copy the data out" implementation
+ // with a null destination.
+ if (DEBUG) Log.i(TAG, "[ skipping data from unsupported domain " + domain + "]");
+ FullBackup.restoreFile(data, size, type, mode, mtime, null);
+ }
}
// ----- Core implementation -----
@@ -215,7 +464,6 @@
public void doBackup(ParcelFileDescriptor oldState,
ParcelFileDescriptor data,
ParcelFileDescriptor newState,
- boolean storeApk,
int token, IBackupManager callbackBinder) throws RemoteException {
// Ensure that we're running with the app's normal permission level
long ident = Binder.clearCallingIdentity();
@@ -223,10 +471,6 @@
if (DEBUG) Log.v(TAG, "doBackup() invoked");
BackupDataOutput output = new BackupDataOutput(data.getFileDescriptor());
- if (storeApk) {
- onSaveApk(output);
- }
-
try {
BackupAgent.this.onBackup(oldState, output, newState);
} catch (IOException ex) {
@@ -273,6 +517,32 @@
}
@Override
+ public void doFullBackup(ParcelFileDescriptor data,
+ int token, IBackupManager callbackBinder) {
+ // Ensure that we're running with the app's normal permission level
+ long ident = Binder.clearCallingIdentity();
+
+ if (DEBUG) Log.v(TAG, "doFullBackup() invoked");
+
+ try {
+ BackupAgent.this.onFullBackup(new FullBackupDataOutput(data));
+ } catch (IOException ex) {
+ Log.d(TAG, "onBackup (" + BackupAgent.this.getClass().getName() + ") threw", ex);
+ throw new RuntimeException(ex);
+ } catch (RuntimeException ex) {
+ Log.d(TAG, "onBackup (" + BackupAgent.this.getClass().getName() + ") threw", ex);
+ throw ex;
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ try {
+ callbackBinder.opComplete(token);
+ } catch (RemoteException e) {
+ // we'll time out anyway, so we're safe
+ }
+ }
+ }
+
+ @Override
public void doRestoreFile(ParcelFileDescriptor data, long size,
int type, String domain, String path, long mode, long mtime,
int token, IBackupManager callbackBinder) throws RemoteException {
diff --git a/core/java/android/app/backup/FullBackup.java b/core/java/android/app/backup/FullBackup.java
index 3b70e19..d7f1c9f 100644
--- a/core/java/android/app/backup/FullBackup.java
+++ b/core/java/android/app/backup/FullBackup.java
@@ -16,6 +16,9 @@
package android.app.backup;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
import android.os.ParcelFileDescriptor;
import android.util.Log;
@@ -29,7 +32,8 @@
/**
* Global constant definitions et cetera related to the full-backup-to-fd
- * binary format.
+ * binary format. Nothing in this namespace is part of any API; it's all
+ * hidden details of the current implementation gathered into one location.
*
* @hide
*/
@@ -52,18 +56,41 @@
public static final String FULL_RESTORE_INTENT_ACTION = "fullrest";
public static final String CONF_TOKEN_INTENT_EXTRA = "conftoken";
- public static final int TYPE_EOF = 0;
- public static final int TYPE_FILE = 1;
- public static final int TYPE_DIRECTORY = 2;
- public static final int TYPE_SYMLINK = 3;
-
+ /**
+ * @hide
+ */
static public native int backupToTar(String packageName, String domain,
String linkdomain, String rootpath, String path, BackupDataOutput output);
- static public void restoreToFile(ParcelFileDescriptor data,
- long size, int type, long mode, long mtime, File outFile,
- boolean doChmod) throws IOException {
- if (type == FullBackup.TYPE_DIRECTORY) {
+ /**
+ * Copy data from a socket to the given File location on permanent storage. The
+ * modification time and access mode of the resulting file will be set if desired.
+ * If the {@code type} parameter indicates that the result should be a directory,
+ * the socket parameter may be {@code null}; even if it is valid, no data will be
+ * read from it in this case.
+ * <p>
+ * If the {@code mode} argument is negative, then the resulting output file will not
+ * have its access mode or last modification time reset as part of this operation.
+ *
+ * @param data Socket supplying the data to be copied to the output file. If the
+ * output is a directory, this may be {@code null}.
+ * @param size Number of bytes of data to copy from the socket to the file. At least
+ * this much data must be available through the {@code data} parameter.
+ * @param type Must be either {@link BackupAgent#TYPE_FILE} for ordinary file data
+ * or {@link BackupAgent#TYPE_DIRECTORY} for a directory.
+ * @param mode Unix-style file mode (as used by the chmod(2) syscall) to be set on
+ * the output file or directory. If this parameter is negative then neither
+ * the mode nor the mtime parameters will be used.
+ * @param mtime A timestamp in the standard Unix epoch that will be imposed as the
+ * last modification time of the output file. if the {@code mode} parameter is
+ * negative then this parameter will be ignored.
+ * @param outFile Location within the filesystem to place the data. This must point
+ * to a location that is writeable by the caller, prefereably using an absolute path.
+ * @throws IOException
+ */
+ static public void restoreFile(ParcelFileDescriptor data,
+ long size, int type, long mode, long mtime, File outFile) throws IOException {
+ if (type == BackupAgent.TYPE_DIRECTORY) {
// Canonically a directory has no associated content, so we don't need to read
// anything from the pipe in this case. Just create the directory here and
// drop down to the final metadata adjustment.
@@ -117,7 +144,7 @@
}
// Now twiddle the state to match the backup, assuming all went well
- if (doChmod && outFile != null) {
+ if (mode >= 0 && outFile != null) {
try {
Libcore.os.chmod(outFile.getPath(), (int)mode);
} catch (ErrnoException e) {
diff --git a/core/java/android/app/backup/FullBackupAgent.java b/core/java/android/app/backup/FullBackupAgent.java
index df1c363..faea76a 100644
--- a/core/java/android/app/backup/FullBackupAgent.java
+++ b/core/java/android/app/backup/FullBackupAgent.java
@@ -16,210 +16,26 @@
package android.app.backup;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.os.Environment;
import android.os.ParcelFileDescriptor;
-import android.util.Log;
-
-import libcore.io.Libcore;
-import libcore.io.ErrnoException;
-import libcore.io.OsConstants;
-import libcore.io.StructStat;
-
-import java.io.File;
import java.io.IOException;
-import java.util.HashSet;
-import java.util.LinkedList;
/**
- * Backs up an application's entire /data/data/<package>/... file system. This
- * class is used by the desktop full backup mechanism and is not intended for direct
- * use by applications.
+ * Simple concrete class that merely provides the default BackupAgent full backup/restore
+ * implementations for applications that do not supply their own.
*
* {@hide}
*/
public class FullBackupAgent extends BackupAgent {
- // !!! TODO: turn off debugging
- private static final String TAG = "FullBackupAgent";
- private static final boolean DEBUG = true;
-
- PackageManager mPm;
-
- private String mMainDir;
- private String mFilesDir;
- private String mDatabaseDir;
- private String mSharedPrefsDir;
- private String mCacheDir;
- private String mLibDir;
-
- private File NULL_FILE;
-
- @Override
- public void onCreate() {
- NULL_FILE = new File("/dev/null");
-
- mPm = getPackageManager();
- try {
- ApplicationInfo appInfo = mPm.getApplicationInfo(getPackageName(), 0);
- mMainDir = new File(appInfo.dataDir).getAbsolutePath();
- } catch (PackageManager.NameNotFoundException e) {
- Log.e(TAG, "Unable to find package " + getPackageName());
- throw new RuntimeException(e);
- }
-
- mFilesDir = getFilesDir().getAbsolutePath();
- mDatabaseDir = getDatabasePath("foo").getParentFile().getAbsolutePath();
- mSharedPrefsDir = getSharedPrefsFile("foo").getParentFile().getAbsolutePath();
- mCacheDir = getCacheDir().getAbsolutePath();
-
- ApplicationInfo app = getApplicationInfo();
- mLibDir = (app.nativeLibraryDir != null)
- ? new File(app.nativeLibraryDir).getAbsolutePath()
- : null;
- }
-
@Override
public void onBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
ParcelFileDescriptor newState) throws IOException {
- // Filters, the scan queue, and the set of resulting entities
- HashSet<String> filterSet = new HashSet<String>();
- String packageName = getPackageName();
-
- // Okay, start with the app's root tree, but exclude all of the canonical subdirs
- if (mLibDir != null) {
- filterSet.add(mLibDir);
- }
- filterSet.add(mCacheDir);
- filterSet.add(mDatabaseDir);
- filterSet.add(mSharedPrefsDir);
- filterSet.add(mFilesDir);
- processTree(packageName, FullBackup.ROOT_TREE_TOKEN, mMainDir, filterSet, data);
-
- // Now do the same for the files dir, db dir, and shared prefs dir
- filterSet.add(mMainDir);
- filterSet.remove(mFilesDir);
- processTree(packageName, FullBackup.DATA_TREE_TOKEN, mFilesDir, filterSet, data);
-
- filterSet.add(mFilesDir);
- filterSet.remove(mDatabaseDir);
- processTree(packageName, FullBackup.DATABASE_TREE_TOKEN, mDatabaseDir, filterSet, data);
-
- filterSet.add(mDatabaseDir);
- filterSet.remove(mSharedPrefsDir);
- processTree(packageName, FullBackup.SHAREDPREFS_TREE_TOKEN, mSharedPrefsDir, filterSet, data);
+ // Doesn't do incremental backup/restore
}
- // Scan the dir tree (if it actually exists) and process each entry we find. If the
- // 'excludes' parameter is non-null, it is consulted each time a new file system entity
- // is visited to see whether that entity (and its subtree, if appropriate) should be
- // omitted from the backup process.
- protected void processTree(String packageName, String domain, String rootPath,
- HashSet<String> excludes, BackupDataOutput data) {
- File rootFile = new File(rootPath);
- if (rootFile.exists()) {
- LinkedList<File> scanQueue = new LinkedList<File>();
- scanQueue.add(rootFile);
-
- while (scanQueue.size() > 0) {
- File file = scanQueue.remove(0);
- String filePath = file.getAbsolutePath();
-
- // prune this subtree?
- if (excludes != null && excludes.contains(filePath)) {
- continue;
- }
-
- // If it's a directory, enqueue its contents for scanning.
- try {
- StructStat stat = Libcore.os.lstat(filePath);
- if (OsConstants.S_ISLNK(stat.st_mode)) {
- if (DEBUG) Log.i(TAG, "Symlink (skipping)!: " + file);
- continue;
- } else if (OsConstants.S_ISDIR(stat.st_mode)) {
- File[] contents = file.listFiles();
- if (contents != null) {
- for (File entry : contents) {
- scanQueue.add(0, entry);
- }
- }
- }
- } catch (ErrnoException e) {
- if (DEBUG) Log.w(TAG, "Error scanning file " + file + " : " + e);
- continue;
- }
-
- // Finally, back this file up before proceeding
- FullBackup.backupToTar(packageName, domain, null, rootPath, filePath, data);
- }
- }
- }
-
- @Override
- void onSaveApk(BackupDataOutput data) {
- ApplicationInfo app = getApplicationInfo();
- if (DEBUG) Log.i(TAG, "APK flags: system=" + ((app.flags & ApplicationInfo.FLAG_SYSTEM) != 0)
- + " updated=" + ((app.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0)
- + " locked=" + ((app.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0) );
- if (DEBUG) Log.i(TAG, "codepath: " + getPackageCodePath());
-
- // Forward-locked apps, system-bundled .apks, etc are filtered out before we get here
- final String pkgName = getPackageName();
- final String apkDir = new File(getPackageCodePath()).getParent();
- FullBackup.backupToTar(pkgName, FullBackup.APK_TREE_TOKEN, null,
- apkDir, getPackageCodePath(), data);
-
- // Save associated .obb content if it exists and we did save the apk
- // check for .obb and save those too
- final File obbDir = Environment.getExternalStorageAppObbDirectory(pkgName);
- if (obbDir != null) {
- if (DEBUG) Log.i(TAG, "obb dir: " + obbDir.getAbsolutePath());
- File[] obbFiles = obbDir.listFiles();
- if (obbFiles != null) {
- final String obbDirName = obbDir.getAbsolutePath();
- for (File obb : obbFiles) {
- FullBackup.backupToTar(pkgName, FullBackup.OBB_TREE_TOKEN, null,
- obbDirName, obb.getAbsolutePath(), data);
- }
- }
- }
- }
-
- /**
- * Dummy -- We're never used for restore of an incremental dataset
- */
@Override
public void onRestore(BackupDataInput data, int appVersionCode, ParcelFileDescriptor newState)
throws IOException {
- }
-
- /**
- * Restore the described file from the given pipe.
- */
- @Override
- public void onRestoreFile(ParcelFileDescriptor data, long size,
- int type, String domain, String relpath, long mode, long mtime)
- throws IOException {
- String basePath = null;
- File outFile = null;
-
- if (DEBUG) Log.d(TAG, "onRestoreFile() size=" + size + " type=" + type
- + " domain=" + domain + " relpath=" + relpath + " mode=" + mode
- + " mtime=" + mtime);
-
- // Parse out the semantic domains into the correct physical location
- if (domain.equals(FullBackup.DATA_TREE_TOKEN)) basePath = mFilesDir;
- else if (domain.equals(FullBackup.DATABASE_TREE_TOKEN)) basePath = mDatabaseDir;
- else if (domain.equals(FullBackup.ROOT_TREE_TOKEN)) basePath = mMainDir;
- else if (domain.equals(FullBackup.SHAREDPREFS_TREE_TOKEN)) basePath = mSharedPrefsDir;
-
- // Not a supported output location? We need to consume the data
- // anyway, so send it to /dev/null
- outFile = (basePath != null) ? new File(basePath, relpath) : null;
- if (DEBUG) Log.i(TAG, "[" + domain + " : " + relpath + "] mapped to " + outFile.getPath());
-
- // Now that we've figured out where the data goes, send it on its way
- FullBackup.restoreToFile(data, size, type, mode, mtime, outFile, true);
+ // Doesn't do incremental backup/restore
}
}
diff --git a/core/java/android/app/backup/FullBackupDataOutput.java b/core/java/android/app/backup/FullBackupDataOutput.java
new file mode 100644
index 0000000..99dab1f
--- /dev/null
+++ b/core/java/android/app/backup/FullBackupDataOutput.java
@@ -0,0 +1,21 @@
+package android.app.backup;
+
+import android.os.ParcelFileDescriptor;
+
+/**
+ * Provides the interface through which a {@link BackupAgent} writes entire files
+ * to a full backup data set, via its {@link BackupAgent#onFullBackup(FullBackupDataOutput)}
+ * method.
+ */
+public class FullBackupDataOutput {
+ // Currently a name-scoping shim around BackupDataOutput
+ private BackupDataOutput mData;
+
+ /** @hide */
+ public FullBackupDataOutput(ParcelFileDescriptor fd) {
+ mData = new BackupDataOutput(fd.getFileDescriptor());
+ }
+
+ /** @hide */
+ public BackupDataOutput getData() { return mData; }
+}
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 454cb31..ddb6ef0 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -91,15 +91,6 @@
public String backupAgentName;
/**
- * Class implementing the package's *full* backup functionality. This
- * is not usable except by system-installed packages. It can be the same
- * as the backupAgent.
- *
- * @hide
- */
- public String fullBackupAgentName;
-
- /**
* Value for {@link #flags}: if set, this application is installed in the
* device's system image.
*/
@@ -555,7 +546,6 @@
dest.writeInt(installLocation);
dest.writeString(manageSpaceActivityName);
dest.writeString(backupAgentName);
- dest.writeString(fullBackupAgentName);
dest.writeInt(descriptionRes);
}
@@ -593,7 +583,6 @@
installLocation = source.readInt();
manageSpaceActivityName = source.readString();
backupAgentName = source.readString();
- fullBackupAgentName = source.readString();
descriptionRes = source.readInt();
}
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 208869b..53d6bb1 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -1517,17 +1517,6 @@
}
}
- // fullBackupAgent is explicitly handled even if allowBackup is false
- name = sa.getNonConfigurationString(
- com.android.internal.R.styleable.AndroidManifestApplication_fullBackupAgent, 0);
- if (name != null) {
- ai.fullBackupAgentName = buildClassName(pkgName, name, outError);
- if (false) {
- Log.v(TAG, "android:fullBackupAgent=" + ai.fullBackupAgentName
- + " from " + pkgName + "+" + name);
- }
- }
-
TypedValue v = sa.peekValue(
com.android.internal.R.styleable.AndroidManifestApplication_label);
if (v != null && (ai.labelRes=v.resourceId) == 0) {
diff --git a/services/java/com/android/server/DnsPinger.java b/core/java/android/net/DnsPinger.java
similarity index 99%
rename from services/java/com/android/server/DnsPinger.java
rename to core/java/android/net/DnsPinger.java
index 4e33938..f2d84eb 100644
--- a/services/java/com/android/server/DnsPinger.java
+++ b/core/java/android/net/DnsPinger.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.server;
+package android.net;
import android.content.Context;
import android.net.ConnectivityManager;
diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl
index fcf4796..f230526 100644
--- a/core/java/android/os/INetworkManagementService.aidl
+++ b/core/java/android/os/INetworkManagementService.aidl
@@ -241,4 +241,23 @@
*/
int getInterfaceTxThrottle(String iface);
+ /**
+ * Sets the name of the default interface in the DNS resolver.
+ */
+ void setDefaultInterfaceForDns(String iface);
+
+ /**
+ * Bind name servers to an interface in the DNS resolver.
+ */
+ void setDnsServersForInterface(String iface, in String[] servers);
+
+ /**
+ * Flush the DNS cache associated with the default interface
+ */
+ void flushDefaultDnsCache();
+
+ /**
+ * Flush the DNS cache associated with the specified interface
+ */
+ void flushInterfaceDnsCache(String iface);
}
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index 05e39ac..673b187 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -522,6 +522,9 @@
argsForZygote.add("--runtime-init");
argsForZygote.add("--setuid=" + uid);
argsForZygote.add("--setgid=" + gid);
+ if ((debugFlags & Zygote.DEBUG_ENABLE_JNI_LOGGING) != 0) {
+ argsForZygote.add("--enable-jni-logging");
+ }
if ((debugFlags & Zygote.DEBUG_ENABLE_SAFEMODE) != 0) {
argsForZygote.add("--enable-safemode");
}
diff --git a/core/java/android/provider/CallLog.java b/core/java/android/provider/CallLog.java
index 39c6f57..382fcf3 100644
--- a/core/java/android/provider/CallLog.java
+++ b/core/java/android/provider/CallLog.java
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+
package android.provider;
import com.android.internal.telephony.CallerInfo;
diff --git a/core/java/android/provider/VoicemailContract.java b/core/java/android/provider/VoicemailContract.java
index 7ea0fbd..d0712d5 100644
--- a/core/java/android/provider/VoicemailContract.java
+++ b/core/java/android/provider/VoicemailContract.java
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License
*/
+
package android.provider;
import android.content.Intent;
diff --git a/core/java/android/view/MotionEvent.java b/core/java/android/view/MotionEvent.java
index 88f59d4..72263a7 100644
--- a/core/java/android/view/MotionEvent.java
+++ b/core/java/android/view/MotionEvent.java
@@ -2881,6 +2881,10 @@
msg.append(", id[").append(i).append("]=").append(getPointerId(i));
msg.append(", x[").append(i).append("]=").append(getX(i));
msg.append(", y[").append(i).append("]=").append(getY(i));
+ msg.append(", pressure[").append(i).append("]=").append(getPressure(i));
+ msg.append(", touchMajor[").append(i).append("]=").append(getTouchMajor(i));
+ msg.append(", touchMinor[").append(i).append("]=").append(getTouchMinor(i));
+ msg.append(", orientation[").append(i).append("]=").append(getOrientation(i));
msg.append(", toolType[").append(i).append("]=").append(
toolTypeToString(getToolType(i)));
}
diff --git a/core/java/android/webkit/CallbackProxy.java b/core/java/android/webkit/CallbackProxy.java
index f7d55f6..0294e3f 100644
--- a/core/java/android/webkit/CallbackProxy.java
+++ b/core/java/android/webkit/CallbackProxy.java
@@ -119,6 +119,7 @@
private static final int NOTIFY_SEARCHBOX_LISTENERS = 139;
private static final int AUTO_LOGIN = 140;
private static final int CLIENT_CERT_REQUEST = 141;
+ private static final int SEARCHBOX_IS_SUPPORTED_CALLBACK = 142;
// Message triggered by the client to resume execution
private static final int NOTIFY = 200;
@@ -796,13 +797,14 @@
mWebChromeClient.setInstallableWebApp();
}
break;
- case NOTIFY_SEARCHBOX_LISTENERS:
+ case NOTIFY_SEARCHBOX_LISTENERS: {
SearchBoxImpl searchBox = (SearchBoxImpl) mWebView.getSearchBox();
@SuppressWarnings("unchecked")
List<String> suggestions = (List<String>) msg.obj;
searchBox.handleSuggestions(msg.getData().getString("query"), suggestions);
break;
+ }
case AUTO_LOGIN: {
if (mWebViewClient != null) {
String realm = msg.getData().getString("realm");
@@ -813,6 +815,12 @@
}
break;
}
+ case SEARCHBOX_IS_SUPPORTED_CALLBACK: {
+ SearchBoxImpl searchBox = (SearchBoxImpl) mWebView.getSearchBox();
+ Boolean supported = (Boolean) msg.obj;
+ searchBox.handleIsSupportedCallback(supported);
+ break;
+ }
}
}
@@ -1627,4 +1635,10 @@
sendMessage(msg);
}
+
+ void onIsSupportedCallback(boolean isSupported) {
+ Message msg = obtainMessage(SEARCHBOX_IS_SUPPORTED_CALLBACK);
+ msg.obj = new Boolean(isSupported);
+ sendMessage(msg);
+ }
}
diff --git a/core/java/android/webkit/SearchBox.java b/core/java/android/webkit/SearchBox.java
index 57c7b03..5075302 100644
--- a/core/java/android/webkit/SearchBox.java
+++ b/core/java/android/webkit/SearchBox.java
@@ -83,10 +83,19 @@
void removeSearchBoxListener(SearchBoxListener l);
/**
+ * Indicates if the searchbox API is supported in the current page.
+ */
+ void isSupported(IsSupportedCallback callback);
+
+ /**
* Listeners (if any) will be called on the thread that created the
* webview.
*/
interface SearchBoxListener {
void onSuggestionsReceived(String query, List<String> suggestions);
}
+
+ interface IsSupportedCallback {
+ void searchBoxIsSupported(boolean supported);
+ }
}
diff --git a/core/java/android/webkit/SearchBoxImpl.java b/core/java/android/webkit/SearchBoxImpl.java
index 480f5d7..61fb2ce 100644
--- a/core/java/android/webkit/SearchBoxImpl.java
+++ b/core/java/android/webkit/SearchBoxImpl.java
@@ -92,9 +92,19 @@
= "if (window.chrome && window.chrome.searchBox &&"
+ " window.chrome.searchBox.on%1$s) { window.chrome.searchBox.on%1$s(); }";
+ private static final String IS_SUPPORTED_SCRIPT
+ = "if (window.searchBoxJavaBridge_) {"
+ + " if (window.chrome && window.chrome.searchBox && "
+ + " window.chrome.searchBox.onsubmit) {"
+ + " window.searchBoxJavaBridge_.isSupportedCallback(true);"
+ + " } else {"
+ + " window.searchBoxJavaBridge_.isSupportedCallback(false);"
+ + " }}";
+
private final List<SearchBoxListener> mListeners;
private final WebViewCore mWebViewCore;
private final CallbackProxy mCallbackProxy;
+ private IsSupportedCallback mSupportedCallback;
SearchBoxImpl(WebViewCore webViewCore, CallbackProxy callbackProxy) {
mListeners = new ArrayList<SearchBoxListener>();
@@ -173,6 +183,25 @@
}
}
+ @Override
+ public void isSupported(IsSupportedCallback callback) {
+ mSupportedCallback = callback;
+ dispatchJs(IS_SUPPORTED_SCRIPT);
+ }
+
+ // Called by Javascript through the Java bridge.
+ public void isSupportedCallback(boolean isSupported) {
+ mCallbackProxy.onIsSupportedCallback(isSupported);
+ }
+
+ public void handleIsSupportedCallback(boolean isSupported) {
+ IsSupportedCallback callback = mSupportedCallback;
+ mSupportedCallback = null;
+ if (callback != null) {
+ callback.searchBoxIsSupported(isSupported);
+ }
+ }
+
// This is used as a hackish alternative to javascript escaping.
// There appears to be no such functionality in the core framework.
private String jsonSerialize(String query) {
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 7ba86a5..ffa52d1 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -3467,6 +3467,40 @@
return Math.min(duration, MAX_DURATION);
}
+
+ // Helper to build a TouchEventData object from a MotionEvent object.
+ // A few fields are allocated now but will be set later:
+ // mAction, mPoints and mPointsInView.
+ private static TouchEventData buildTouchFromEvent(MotionEvent ev) {
+ TouchEventData ted = new TouchEventData();
+ ted.mAction = ev.getActionMasked();
+ ted.mEventTime = ev.getEventTime();
+
+ final int count = ev.getPointerCount();
+ ted.mIds = new int[count];
+ ted.mPoints = new Point[count];
+ ted.mPointsInView = new Point[count];
+ ted.mPressures = new float[count];
+ ted.mTouchMajor = new int[count];
+ ted.mTouchMinor = new int[count];
+ ted.mOrientation = new float[count];
+ for (int c = 0; c < count; c++) {
+ ted.mIds[c] = ev.getPointerId(c);
+ ted.mPressures[c] = ev.getPressure(c);
+ ted.mTouchMajor[c] = (int) ev.getTouchMajor(c);
+ ted.mTouchMinor[c] = (int) ev.getTouchMinor(c);
+ ted.mOrientation[c] = ev.getOrientation(c);
+ }
+
+ if (ted.mAction == MotionEvent.ACTION_POINTER_DOWN
+ || ted.mAction == MotionEvent.ACTION_POINTER_UP) {
+ ted.mActionIndex = ev.getActionIndex();
+ }
+ ted.mMetaState = ev.getMetaState();
+
+ return ted;
+ }
+
// helper to pin the scrollBy parameters (already in view coordinates)
// returns true if the scroll was changed
private boolean pinScrollBy(int dx, int dy, boolean animate, int animationDuration) {
@@ -5865,15 +5899,10 @@
}
// pass the touch events from UI thread to WebCore thread
if (shouldForwardTouchEvent()) {
- TouchEventData ted = new TouchEventData();
+ TouchEventData ted = buildTouchFromEvent(ev);
ted.mAction = action;
- ted.mIds = new int[1];
- ted.mIds[0] = ev.getPointerId(0);
- ted.mPoints = new Point[1];
ted.mPoints[0] = new Point(contentX, contentY);
- ted.mPointsInView = new Point[1];
ted.mPointsInView[0] = new Point(x, y);
- ted.mMetaState = ev.getMetaState();
ted.mReprocess = mDeferTouchProcess;
ted.mNativeLayer = nativeScrollableLayer(
contentX, contentY, ted.mNativeLayerRect, null);
@@ -5915,15 +5944,10 @@
// pass the touch events from UI thread to WebCore thread
if (shouldForwardTouchEvent() && mConfirmMove && (firstMove
|| eventTime - mLastSentTouchTime > mCurrentTouchInterval)) {
- TouchEventData ted = new TouchEventData();
+ TouchEventData ted = buildTouchFromEvent(ev);
ted.mAction = action;
- ted.mIds = new int[1];
- ted.mIds[0] = ev.getPointerId(0);
- ted.mPoints = new Point[1];
ted.mPoints[0] = new Point(contentX, contentY);
- ted.mPointsInView = new Point[1];
ted.mPointsInView[0] = new Point(x, y);
- ted.mMetaState = ev.getMetaState();
ted.mReprocess = mDeferTouchProcess;
ted.mNativeLayer = mScrollingLayer;
ted.mNativeLayerRect.set(mScrollingLayerRect);
@@ -6093,15 +6117,10 @@
if (!isFocused()) requestFocus();
// pass the touch events from UI thread to WebCore thread
if (shouldForwardTouchEvent()) {
- TouchEventData ted = new TouchEventData();
- ted.mIds = new int[1];
- ted.mIds[0] = ev.getPointerId(0);
+ TouchEventData ted = buildTouchFromEvent(ev);
ted.mAction = action;
- ted.mPoints = new Point[1];
ted.mPoints[0] = new Point(contentX, contentY);
- ted.mPointsInView = new Point[1];
ted.mPointsInView[0] = new Point(x, y);
- ted.mMetaState = ev.getMetaState();
ted.mReprocess = mDeferTouchProcess;
ted.mNativeLayer = mScrollingLayer;
ted.mNativeLayerRect.set(mScrollingLayerRect);
@@ -6118,15 +6137,10 @@
mPrivateHandler.removeMessages(SWITCH_TO_SHORTPRESS);
mPrivateHandler.removeMessages(SWITCH_TO_LONGPRESS);
if (inFullScreenMode() || mDeferTouchProcess) {
- TouchEventData ted = new TouchEventData();
- ted.mIds = new int[1];
- ted.mIds[0] = ev.getPointerId(0);
+ TouchEventData ted = buildTouchFromEvent(ev);
ted.mAction = WebViewCore.ACTION_DOUBLETAP;
- ted.mPoints = new Point[1];
ted.mPoints[0] = new Point(contentX, contentY);
- ted.mPointsInView = new Point[1];
ted.mPointsInView[0] = new Point(x, y);
- ted.mMetaState = ev.getMetaState();
ted.mReprocess = mDeferTouchProcess;
ted.mNativeLayer = nativeScrollableLayer(
contentX, contentY,
@@ -6258,24 +6272,14 @@
}
private void passMultiTouchToWebKit(MotionEvent ev, long sequence) {
- TouchEventData ted = new TouchEventData();
- ted.mAction = ev.getActionMasked();
- final int count = ev.getPointerCount();
- ted.mIds = new int[count];
- ted.mPoints = new Point[count];
- ted.mPointsInView = new Point[count];
- for (int c = 0; c < count; c++) {
+ TouchEventData ted = buildTouchFromEvent(ev);
+ for (int c = 0; c < ev.getPointerCount(); c++) {
ted.mIds[c] = ev.getPointerId(c);
int x = viewToContentX((int) ev.getX(c) + mScrollX);
int y = viewToContentY((int) ev.getY(c) + mScrollY);
ted.mPoints[c] = new Point(x, y);
ted.mPointsInView[c] = new Point((int) ev.getX(c), (int) ev.getY(c));
}
- if (ted.mAction == MotionEvent.ACTION_POINTER_DOWN
- || ted.mAction == MotionEvent.ACTION_POINTER_UP) {
- ted.mActionIndex = ev.getActionIndex();
- }
- ted.mMetaState = ev.getMetaState();
ted.mReprocess = true;
ted.mMotionEvent = MotionEvent.obtain(ev);
ted.mSequence = sequence;
@@ -6349,7 +6353,11 @@
if (removeEvents) {
mWebViewCore.removeMessages(EventHub.TOUCH_EVENT);
}
+
TouchEventData ted = new TouchEventData();
+ ted.mAction = MotionEvent.ACTION_CANCEL;
+ ted.mEventTime = mLastTouchTime;
+ ted.mMetaState = 0;
ted.mIds = new int[1];
ted.mIds[0] = 0;
ted.mPoints = new Point[1];
@@ -6358,7 +6366,15 @@
int viewX = contentToViewX(x) - mScrollX;
int viewY = contentToViewY(y) - mScrollY;
ted.mPointsInView[0] = new Point(viewX, viewY);
- ted.mAction = MotionEvent.ACTION_CANCEL;
+ ted.mPressures = new float[1];
+ ted.mPressures[0] = 1;
+ ted.mTouchMajor = new int[1];
+ ted.mTouchMajor[0] = 1;
+ ted.mTouchMinor = new int[1];
+ ted.mTouchMinor[0] = 1;
+ ted.mOrientation = new float[1];
+ ted.mOrientation[0] = 0;
+
ted.mNativeLayer = nativeScrollableLayer(
x, y, ted.mNativeLayerRect, null);
ted.mSequence = mTouchEventQueue.nextTouchSequence();
@@ -8037,6 +8053,7 @@
if (inFullScreenMode() || mDeferTouchProcess) {
TouchEventData ted = new TouchEventData();
ted.mAction = WebViewCore.ACTION_LONGPRESS;
+ ted.mEventTime = mLastTouchTime;
ted.mIds = new int[1];
ted.mIds[0] = 0;
ted.mPoints = new Point[1];
@@ -8044,6 +8061,15 @@
viewToContentY(mLastTouchY + mScrollY));
ted.mPointsInView = new Point[1];
ted.mPointsInView[0] = new Point(mLastTouchX, mLastTouchY);
+ ted.mPressures = new float[1];
+ ted.mPressures[0] = 1;
+ ted.mTouchMajor = new int[1];
+ ted.mTouchMajor[0] = 1;
+ ted.mTouchMinor = new int[1];
+ ted.mTouchMinor[0] = 1;
+ ted.mOrientation = new float[1];
+ ted.mOrientation[0] = 0;
+
// metaState for long press is tricky. Should it be the
// state when the press started or when the press was
// released? Or some intermediary key state? For
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index 4f97066..3357220 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -577,8 +577,10 @@
private native void nativeTouchUp(int touchGeneration,
int framePtr, int nodePtr, int x, int y);
- private native boolean nativeHandleTouchEvent(int action, int[] idArray,
- int[] xArray, int[] yArray, int count, int actionIndex, int metaState);
+ private native boolean nativeHandleTouchEvent(int action, long eventTime,
+ int[] idArray, int[] xArray, int[] yArray, float[] pressureArray,
+ int[] touchMajorArray, int[] touchMinorArray, float[] orientationArray,
+ int count, int actionIndex, int metaState);
private native void nativeUpdateFrameCache();
@@ -833,16 +835,21 @@
static class TouchEventData {
int mAction;
- int[] mIds; // Ids of the touch points
+ long mEventTime; // Time (in ms) this event was generated.
+ int[] mIds; // Ids of the touch points.
Point[] mPoints;
- Point[] mPointsInView; // the point coordinates in view axis.
- int mActionIndex; // Associated pointer index for ACTION_POINTER_DOWN/UP
+ Point[] mPointsInView; // Point coordinates in view axis.
+ float[] mPressures; // Pressures of the touch points.
+ int[] mTouchMajor; // Length of the major axis of the touch area.
+ int[] mTouchMinor; // Length of the minor axis of the touch area.
+ float[] mOrientation; // The orientation of the touch area.
+ int mActionIndex; // Associated pointer index for ACTION_POINTER_DOWN/UP.
int mMetaState;
boolean mReprocess;
- MotionEvent mMotionEvent;
+ MotionEvent mMotionEvent; // Only used for multi-touch.
int mNativeLayer;
Rect mNativeLayerRect = new Rect();
- long mSequence;
+ long mSequence; // For queuing the events.
boolean mNativeResult;
}
@@ -1351,8 +1358,11 @@
nativeScrollLayer(ted.mNativeLayer,
ted.mNativeLayerRect);
}
- ted.mNativeResult = nativeHandleTouchEvent(ted.mAction, ted.mIds,
- xArray, yArray, count, ted.mActionIndex, ted.mMetaState);
+ ted.mNativeResult = nativeHandleTouchEvent(
+ ted.mAction, ted.mEventTime, ted.mIds,
+ xArray, yArray, ted.mPressures,
+ ted.mTouchMajor, ted.mTouchMinor, ted.mOrientation,
+ count, ted.mActionIndex, ted.mMetaState);
Message.obtain(
mWebView.mPrivateHandler,
WebView.PREVENT_TOUCH_ID,
diff --git a/core/java/android/webkit/ZoomManager.java b/core/java/android/webkit/ZoomManager.java
index 7d43e94..252fc8f 100644
--- a/core/java/android/webkit/ZoomManager.java
+++ b/core/java/android/webkit/ZoomManager.java
@@ -1111,6 +1111,12 @@
mTextWrapScale = Math.max(mTextWrapScale, overviewScale);
}
reflowText = exceedsMinScaleIncrement(mTextWrapScale, scale);
+ } else {
+ // In case of restored scale, treat defaultScale as overview since
+ // it usually means the previous scale is not saved.
+ if (scale == mDefaultScale && settings.getLoadWithOverviewMode()) {
+ scale = overviewScale;
+ }
}
mInitialZoomOverview = settings.getLoadWithOverviewMode() &&
!exceedsMinScaleIncrement(scale, overviewScale);
diff --git a/core/java/android/widget/LinearLayout.java b/core/java/android/widget/LinearLayout.java
index fc8bce8..427fd3e 100644
--- a/core/java/android/widget/LinearLayout.java
+++ b/core/java/android/widget/LinearLayout.java
@@ -301,49 +301,55 @@
void drawDividersVertical(Canvas canvas) {
final int count = getVirtualChildCount();
- int top = getPaddingTop();
for (int i = 0; i < count; i++) {
final View child = getVirtualChildAt(i);
- if (child == null) {
- top += measureNullChild(i);
- } else if (child.getVisibility() != GONE) {
+ if (child != null && child.getVisibility() != GONE) {
if (hasDividerBeforeChildAt(i)) {
+ final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+ final int top = child.getTop() - lp.topMargin;
drawHorizontalDivider(canvas, top);
- top += mDividerHeight;
}
-
- LayoutParams lp = (LayoutParams) child.getLayoutParams();
- top += lp.topMargin + child.getHeight() + lp.bottomMargin;
}
}
if (hasDividerBeforeChildAt(count)) {
- drawHorizontalDivider(canvas, top);
+ final View child = getVirtualChildAt(count - 1);
+ int bottom = 0;
+ if (child == null) {
+ bottom = getHeight() - getPaddingBottom() - mDividerHeight;
+ } else {
+ final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+ bottom = child.getBottom() + lp.bottomMargin;
+ }
+ drawHorizontalDivider(canvas, bottom);
}
}
void drawDividersHorizontal(Canvas canvas) {
final int count = getVirtualChildCount();
- int left = getPaddingLeft();
for (int i = 0; i < count; i++) {
final View child = getVirtualChildAt(i);
- if (child == null) {
- left += measureNullChild(i);
- } else if (child.getVisibility() != GONE) {
+ if (child != null && child.getVisibility() != GONE) {
if (hasDividerBeforeChildAt(i)) {
+ final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+ final int left = child.getLeft() - lp.leftMargin;
drawVerticalDivider(canvas, left);
- left += mDividerWidth;
}
-
- LayoutParams lp = (LayoutParams) child.getLayoutParams();
- left += lp.leftMargin + child.getWidth() + lp.rightMargin;
}
}
if (hasDividerBeforeChildAt(count)) {
- drawVerticalDivider(canvas, left);
+ final View child = getVirtualChildAt(count - 1);
+ int right = 0;
+ if (child == null) {
+ right = getWidth() - getPaddingRight() - mDividerWidth;
+ } else {
+ final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+ right = child.getRight() + lp.rightMargin;
+ }
+ drawVerticalDivider(canvas, right);
}
}
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index c91f1a6..772e8e9 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -8901,7 +8901,7 @@
TypedArray styledAttributes = mContext.obtainStyledAttributes(R.styleable.Theme);
boolean allowText = getContext().getResources().getBoolean(
- com.android.internal.R.bool.allow_action_menu_item_text_with_icon);
+ com.android.internal.R.bool.config_allowActionMenuItemTextWithIcon);
mode.setTitle(allowText ?
mContext.getString(com.android.internal.R.string.textSelectionCABTitle) : null);
diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java
index b872e22..7cb002c 100644
--- a/core/java/com/android/internal/os/ZygoteConnection.java
+++ b/core/java/com/android/internal/os/ZygoteConnection.java
@@ -328,8 +328,8 @@
boolean peerWait;
/**
- * From --enable-debugger, --enable-checkjni, --enable-assert, and
- * --enable-safemode
+ * From --enable-debugger, --enable-checkjni, --enable-assert,
+ * --enable-safemode, and --enable-jni-logging.
*/
int debugFlags;
@@ -408,6 +408,8 @@
debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
} else if (arg.equals("--enable-checkjni")) {
debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
+ } else if (arg.equals("--enable-jni-logging")) {
+ debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
} else if (arg.equals("--enable-assert")) {
debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
} else if (arg.equals("--peer-wait")) {
diff --git a/core/java/com/android/internal/view/menu/ActionMenuItemView.java b/core/java/com/android/internal/view/menu/ActionMenuItemView.java
index 479788d..3b497e4 100644
--- a/core/java/com/android/internal/view/menu/ActionMenuItemView.java
+++ b/core/java/com/android/internal/view/menu/ActionMenuItemView.java
@@ -17,6 +17,7 @@
package com.android.internal.view.menu;
import android.content.Context;
+import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import android.util.AttributeSet;
@@ -38,17 +39,24 @@
private ImageButton mImageButton;
private Button mTextButton;
+ private boolean mAllowTextWithIcon;
+ private boolean mShowTextAllCaps;
+ private boolean mExpandedFormat;
public ActionMenuItemView(Context context) {
this(context, null);
}
public ActionMenuItemView(Context context, AttributeSet attrs) {
- super(context, attrs);
+ this(context, attrs, 0);
}
public ActionMenuItemView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
+ final Resources res = context.getResources();
+ mAllowTextWithIcon = res.getBoolean(
+ com.android.internal.R.bool.config_allowActionMenuItemTextWithIcon);
+ mShowTextAllCaps = res.getBoolean(com.android.internal.R.bool.config_actionMenuItemAllCaps);
}
@Override
@@ -104,9 +112,20 @@
// TODO Support checkable action items
}
+ public void setExpandedFormat(boolean expandedFormat) {
+ if (mExpandedFormat != expandedFormat) {
+ mExpandedFormat = expandedFormat;
+ if (mItemData != null) {
+ mItemData.actionFormatChanged();
+ }
+ }
+ }
+
private void updateTextButtonVisibility() {
boolean visible = !TextUtils.isEmpty(mTextButton.getText());
- visible = visible && (mImageButton.getDrawable() == null || mItemData.showsTextAsAction());
+ visible &= mImageButton.getDrawable() == null ||
+ (mItemData.showsTextAsAction() && (mAllowTextWithIcon || mExpandedFormat));
+
mTextButton.setVisibility(visible ? VISIBLE : GONE);
}
@@ -135,7 +154,12 @@
// populate accessibility description with title
setContentDescription(title);
- mTextButton.setText(mTitle);
+ if (mShowTextAllCaps && title != null) {
+ mTextButton.setText(title.toString().toUpperCase(
+ getContext().getResources().getConfiguration().locale));
+ } else {
+ mTextButton.setText(mTitle);
+ }
updateTextButtonVisibility();
}
diff --git a/core/java/com/android/internal/view/menu/ActionMenuPresenter.java b/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
index 2fec9cd..b86eb13 100644
--- a/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
+++ b/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
@@ -19,8 +19,8 @@
import com.android.internal.view.menu.ActionMenuView.ActionMenuChildView;
import android.content.Context;
-import android.content.res.Configuration;
import android.content.res.Resources;
+import android.util.Log;
import android.util.SparseBooleanArray;
import android.view.MenuItem;
import android.view.SoundEffectConstants;
@@ -48,6 +48,8 @@
private boolean mStrictWidthLimit;
private boolean mWidthLimitSet;
+ private int mMinCellSize;
+
// Group IDs that have been added as actions - used temporarily, allocated here for reuse.
private final SparseBooleanArray mActionButtonGroups = new SparseBooleanArray();
@@ -96,6 +98,8 @@
mActionItemWidthLimit = width;
+ mMinCellSize = (int) (ActionMenuView.MIN_CELL_SIZE * res.getDisplayMetrics().density);
+
// Drop a scrap view as it may no longer reflect the proper context/config.
mScrapActionButtonView = null;
}
@@ -126,16 +130,30 @@
@Override
public View getItemView(MenuItemImpl item, View convertView, ViewGroup parent) {
View actionView = item.getActionView();
- actionView = actionView != null && !item.hasCollapsibleActionView() ?
- actionView : super.getItemView(item, convertView, parent);
+ if (actionView == null || item.hasCollapsibleActionView()) {
+ if (!(convertView instanceof ActionMenuItemView)) {
+ convertView = null;
+ }
+ actionView = super.getItemView(item, convertView, parent);
+ }
actionView.setVisibility(item.isActionViewExpanded() ? View.GONE : View.VISIBLE);
+
+ final ActionMenuView menuParent = (ActionMenuView) parent;
+ final ViewGroup.LayoutParams lp = actionView.getLayoutParams();
+ if (!menuParent.checkLayoutParams(lp)) {
+ actionView.setLayoutParams(menuParent.generateLayoutParams(lp));
+ }
return actionView;
}
@Override
public void bindItemView(MenuItemImpl item, MenuView.ItemView itemView) {
itemView.initialize(item, 0);
- ((ActionMenuItemView) itemView).setItemInvoker((ActionMenuView) mMenuView);
+
+ final ActionMenuView menuView = (ActionMenuView) mMenuView;
+ ActionMenuItemView actionItemView = (ActionMenuItemView) itemView;
+ actionItemView.setItemInvoker(menuView);
+ if (false) actionItemView.setExpandedFormat(menuView.isExpandedFormat());
}
@Override
@@ -150,15 +168,14 @@
if (mReserveOverflow && mMenu.getNonActionItems().size() > 0) {
if (mOverflowButton == null) {
mOverflowButton = new OverflowMenuButton(mContext);
- mOverflowButton.setLayoutParams(
- ((ActionMenuView) mMenuView).generateOverflowButtonLayoutParams());
}
ViewGroup parent = (ViewGroup) mOverflowButton.getParent();
if (parent != mMenuView) {
if (parent != null) {
parent.removeView(mOverflowButton);
}
- ((ViewGroup) mMenuView).addView(mOverflowButton);
+ ActionMenuView menuView = (ActionMenuView) mMenuView;
+ menuView.addView(mOverflowButton, menuView.generateOverflowButtonLayoutParams());
}
} else if (mOverflowButton != null && mOverflowButton.getParent() == mMenuView) {
((ViewGroup) mMenuView).removeView(mOverflowButton);
@@ -313,19 +330,29 @@
final SparseBooleanArray seenGroups = mActionButtonGroups;
seenGroups.clear();
+ int cellSize = 0;
+ int cellsRemaining = 0;
+ if (mStrictWidthLimit) {
+ cellsRemaining = widthLimit / mMinCellSize;
+ final int cellSizeRemaining = widthLimit % mMinCellSize;
+ cellSize = mMinCellSize + cellSizeRemaining / cellsRemaining;
+ }
+
// Flag as many more requested items as will fit.
for (int i = 0; i < itemsSize; i++) {
MenuItemImpl item = visibleItems.get(i);
if (item.requiresActionButton()) {
- View v = item.getActionView();
- if (v == null || item.hasCollapsibleActionView()) {
- v = getItemView(item, mScrapActionButtonView, parent);
- if (mScrapActionButtonView == null) {
- mScrapActionButtonView = v;
- }
+ View v = getItemView(item, mScrapActionButtonView, parent);
+ if (mScrapActionButtonView == null) {
+ mScrapActionButtonView = v;
}
- v.measure(querySpec, querySpec);
+ if (mStrictWidthLimit) {
+ cellsRemaining -= ActionMenuView.measureChildForCells(v,
+ cellSize, cellsRemaining, querySpec, 0);
+ } else {
+ v.measure(querySpec, querySpec);
+ }
final int measuredWidth = v.getMeasuredWidth();
widthLimit -= measuredWidth;
if (firstActionWidth == 0) {
@@ -341,18 +368,25 @@
// can break the max actions rule, but not the width limit.
final int groupId = item.getGroupId();
final boolean inGroup = seenGroups.get(groupId);
- boolean isAction = (maxActions > 0 || inGroup) && widthLimit > 0;
+ boolean isAction = (maxActions > 0 || inGroup) && widthLimit > 0 &&
+ (!mStrictWidthLimit || cellsRemaining > 0);
maxActions--;
if (isAction) {
- View v = item.getActionView();
- if (v == null || item.hasCollapsibleActionView()) {
- v = getItemView(item, mScrapActionButtonView, parent);
- if (mScrapActionButtonView == null) {
- mScrapActionButtonView = v;
- }
+ View v = getItemView(item, mScrapActionButtonView, parent);
+ if (mScrapActionButtonView == null) {
+ mScrapActionButtonView = v;
}
- v.measure(querySpec, querySpec);
+ if (mStrictWidthLimit) {
+ final int cells = ActionMenuView.measureChildForCells(v,
+ cellSize, cellsRemaining, querySpec, 0);
+ cellsRemaining -= cells;
+ if (cells == 0) {
+ isAction = false;
+ }
+ } else {
+ v.measure(querySpec, querySpec);
+ }
final int measuredWidth = v.getMeasuredWidth();
widthLimit -= measuredWidth;
if (firstActionWidth == 0) {
@@ -360,10 +394,10 @@
}
if (mStrictWidthLimit) {
- isAction = widthLimit >= 0;
+ isAction &= widthLimit >= 0;
} else {
// Did this push the entire first item past the limit?
- isAction = widthLimit + firstActionWidth > 0;
+ isAction &= widthLimit + firstActionWidth > 0;
}
}
@@ -414,7 +448,7 @@
}
public boolean needsDividerBefore() {
- return true;
+ return false;
}
public boolean needsDividerAfter() {
diff --git a/core/java/com/android/internal/view/menu/ActionMenuView.java b/core/java/com/android/internal/view/menu/ActionMenuView.java
index 7b4f216..cfe9e59 100644
--- a/core/java/com/android/internal/view/menu/ActionMenuView.java
+++ b/core/java/com/android/internal/view/menu/ActionMenuView.java
@@ -30,12 +30,16 @@
public class ActionMenuView extends LinearLayout implements MenuBuilder.ItemInvoker, MenuView {
private static final String TAG = "ActionMenuView";
+ static final int MIN_CELL_SIZE = 56; // dips
+
private MenuBuilder mMenu;
private boolean mReserveOverflow;
private ActionMenuPresenter mPresenter;
private boolean mUpdateContentsBeforeMeasure;
private boolean mFormatItems;
+ private int mMinCellSize;
+ private int mMeasuredExtraWidth;
public ActionMenuView(Context context) {
this(context, null);
@@ -44,12 +48,17 @@
public ActionMenuView(Context context, AttributeSet attrs) {
super(context, attrs);
setBaselineAligned(false);
+ mMinCellSize = (int) (MIN_CELL_SIZE * context.getResources().getDisplayMetrics().density);
}
public void setPresenter(ActionMenuPresenter presenter) {
mPresenter = presenter;
}
+ public boolean isExpandedFormat() {
+ return mFormatItems;
+ }
+
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
@@ -70,13 +79,196 @@
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ // If we've been given an exact size to match, apply special formatting during layout.
+ mFormatItems = MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY;
if (mUpdateContentsBeforeMeasure && mMenu != null) {
mMenu.onItemsChanged(true);
mUpdateContentsBeforeMeasure = false;
}
- // If we've been given an exact size to match, apply special formatting during layout.
- mFormatItems = MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY;
- super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+
+ if (mFormatItems) {
+ onMeasureExactFormat(widthMeasureSpec, heightMeasureSpec);
+ } else {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ }
+ }
+
+ private void onMeasureExactFormat(int widthMeasureSpec, int heightMeasureSpec) {
+ // We already know the width mode is EXACTLY if we're here.
+ final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
+ int widthSize = MeasureSpec.getSize(widthMeasureSpec);
+ int heightSize = MeasureSpec.getSize(heightMeasureSpec);
+
+ final int widthPadding = getPaddingLeft() + getPaddingRight();
+ final int heightPadding = getPaddingTop() + getPaddingBottom();
+
+ widthSize -= widthPadding;
+
+ // Divide the view into cells.
+ final int cellCount = widthSize / mMinCellSize;
+ final int cellSizeRemaining = widthSize % mMinCellSize;
+ final int cellSize = mMinCellSize + cellSizeRemaining / cellCount;
+
+ int cellsRemaining = cellCount;
+ int maxChildHeight = 0;
+ int maxCellsUsed = 0;
+ int multiCellItemCount = 0;
+
+ if (mReserveOverflow) cellsRemaining--;
+
+ final int childCount = getChildCount();
+ for (int i = 0; i < childCount; i++) {
+ final View child = getChildAt(i);
+ final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+ lp.expanded = false;
+ lp.extraPixels = 0;
+ lp.cellsUsed = 0;
+ lp.multiCell = false;
+
+ // Overflow always gets 1 cell. No more, no less.
+ final int cellsAvailable = lp.isOverflowButton ? 1 : cellsRemaining;
+
+ final int cellsUsed = measureChildForCells(child, cellSize, cellsAvailable,
+ heightMeasureSpec, heightPadding);
+
+ maxCellsUsed = Math.max(maxCellsUsed, cellsUsed);
+ if (lp.multiCell) multiCellItemCount++;
+
+ cellsRemaining -= cellsUsed;
+ maxChildHeight = Math.max(maxChildHeight, child.getMeasuredHeight());
+ }
+
+ // Divide space for remaining cells if we have items that can expand.
+ // Try distributing whole leftover cells to smaller items first.
+
+ boolean needsExpansion = false;
+ long smallestMultiCellItemsAt = 0;
+ while (multiCellItemCount > 0 && cellsRemaining > 0) {
+ int minCells = Integer.MAX_VALUE;
+ long minCellsAt = 0; // Bit locations are indices of relevant child views
+ int minCellsItemCount = 0;
+ for (int i = 0; i < childCount; i++) {
+ final View child = getChildAt(i);
+ final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+
+ // Don't try to expand items that shouldn't.
+ if (!lp.multiCell) continue;
+
+ // Mark indices of children that can receive an extra cell.
+ if (lp.cellsUsed < minCells) {
+ minCells = lp.cellsUsed;
+ minCellsAt = 1 << i;
+ minCellsItemCount = 1;
+ } else if (lp.cellsUsed == minCells) {
+ minCellsAt |= 1 << i;
+ minCellsItemCount++;
+ }
+ }
+
+ if (minCellsItemCount < cellsRemaining) break; // Couldn't expand anything evenly. Stop.
+
+ // Items that get expanded will always be in the set of smallest items when we're done.
+ smallestMultiCellItemsAt |= minCellsAt;
+
+ for (int i = 0; i < childCount; i++) {
+ if ((minCellsAt & (1 << i)) == 0) continue;
+
+ final View child = getChildAt(i);
+ final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+ lp.cellsUsed++;
+ lp.expanded = true;
+ cellsRemaining--;
+ }
+
+ needsExpansion = true;
+ }
+
+ // Divide any space left that wouldn't divide along cell boundaries
+ // evenly among the smallest multi-cell (expandable) items.
+
+ if (cellsRemaining > 0 && smallestMultiCellItemsAt != 0) {
+ final int expandCount = Long.bitCount(smallestMultiCellItemsAt);
+ final int extraPixels = cellsRemaining * cellSize / expandCount;
+
+ for (int i = 0; i < childCount; i++) {
+ if ((smallestMultiCellItemsAt & (1 << i)) == 0) continue;
+
+ final View child = getChildAt(i);
+ final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+ lp.extraPixels = extraPixels;
+ lp.expanded = true;
+ }
+
+ needsExpansion = true;
+ cellsRemaining = 0;
+ }
+
+ // Remeasure any items that have had extra space allocated to them.
+ if (needsExpansion) {
+ int heightSpec = MeasureSpec.makeMeasureSpec(heightSize - heightPadding, heightMode);
+ for (int i = 0; i < childCount; i++) {
+ final View child = getChildAt(i);
+ final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+
+ if (!lp.expanded) continue;
+
+ final int width = lp.cellsUsed * cellSize + lp.extraPixels;
+ child.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), heightSpec);
+ }
+ }
+
+ if (heightMode != MeasureSpec.EXACTLY) {
+ heightSize = maxChildHeight;
+ }
+
+ setMeasuredDimension(widthSize, heightSize);
+ mMeasuredExtraWidth = cellsRemaining * cellSize;
+ }
+
+ /**
+ * Measure a child view to fit within cell-based formatting. The child's width
+ * will be measured to a whole multiple of cellSize.
+ *
+ * <p>Sets the multiCell and cellsUsed fields of LayoutParams.
+ *
+ * @param child Child to measure
+ * @param cellSize Size of one cell
+ * @param cellsRemaining Number of cells remaining that this view can expand to fill
+ * @param parentHeightMeasureSpec MeasureSpec used by the parent view
+ * @param parentHeightPadding Padding present in the parent view
+ * @return Number of cells this child was measured to occupy
+ */
+ static int measureChildForCells(View child, int cellSize, int cellsRemaining,
+ int parentHeightMeasureSpec, int parentHeightPadding) {
+ final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+ final ActionMenuItemView itemView = child instanceof ActionMenuItemView ?
+ (ActionMenuItemView) child : null;
+
+ final int childHeightSize = MeasureSpec.getSize(parentHeightMeasureSpec) -
+ parentHeightPadding;
+ final int childHeightMode = MeasureSpec.getMode(parentHeightMeasureSpec);
+ final int childHeightSpec = MeasureSpec.makeMeasureSpec(childHeightSize, childHeightMode);
+
+ int cellsUsed = cellsRemaining > 0 ? 1 : 0;
+ final boolean multiCell = !lp.isOverflowButton &&
+ (itemView == null || itemView.hasText());
+
+ lp.multiCell = multiCell;
+
+ if (multiCell && cellsRemaining > 0) {
+ final int childWidthSpec = MeasureSpec.makeMeasureSpec(
+ cellSize * cellsRemaining, MeasureSpec.AT_MOST);
+ child.measure(childWidthSpec, childHeightSpec);
+
+ final int measuredWidth = child.getMeasuredWidth();
+ cellsUsed = measuredWidth / cellSize;
+ if (measuredWidth % cellSize != 0) cellsUsed++;
+ }
+ lp.cellsUsed = cellsUsed;
+ final int targetWidth = cellsUsed * cellSize;
+ child.measure(MeasureSpec.makeMeasureSpec(targetWidth, MeasureSpec.EXACTLY),
+ childHeightSpec);
+ return cellsUsed;
}
@Override
@@ -93,6 +285,7 @@
int nonOverflowWidth = 0;
int nonOverflowCount = 0;
int widthRemaining = right - left - getPaddingRight() - getPaddingLeft();
+ boolean hasOverflow = false;
for (int i = 0; i < childCount; i++) {
final View v = getChildAt(i);
if (v.getVisibility() == GONE) {
@@ -107,15 +300,18 @@
}
int height = v.getMeasuredHeight();
- int r = getPaddingRight();
+ int r = getWidth() - getPaddingRight();
int l = r - overflowWidth;
int t = midVertical - (height / 2);
int b = t + height;
v.layout(l, t, r, b);
widthRemaining -= overflowWidth;
+ hasOverflow = true;
} else {
- nonOverflowWidth += v.getMeasuredWidth() + p.leftMargin + p.rightMargin;
+ final int size = v.getMeasuredWidth() + p.leftMargin + p.rightMargin;
+ nonOverflowWidth += size;
+ widthRemaining -= size;
if (hasDividerBeforeChildAt(i)) {
nonOverflowWidth += dividerWidth;
}
@@ -123,10 +319,8 @@
}
}
- // Fill action items from the left. Overflow will always pin to the right edge.
- if (nonOverflowWidth <= widthRemaining - overflowWidth) {
- widthRemaining -= overflowWidth;
- }
+ final int spacerCount = nonOverflowCount - (hasOverflow ? 0 : 1);
+ final int spacerSize = spacerCount > 0 ? widthRemaining / spacerCount : 0;
int startLeft = getPaddingLeft();
for (int i = 0; i < childCount; i++) {
@@ -141,7 +335,7 @@
int height = v.getMeasuredHeight();
int t = midVertical - (height / 2);
v.layout(startLeft, t, startLeft + width, t + height);
- startLeft += width + lp.rightMargin;
+ startLeft += width + lp.rightMargin + spacerSize;
}
}
@@ -168,6 +362,11 @@
}
@Override
+ public LayoutParams generateLayoutParams(AttributeSet attrs) {
+ return new LayoutParams(getContext(), attrs);
+ }
+
+ @Override
protected LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
if (p instanceof LayoutParams) {
LayoutParams result = new LayoutParams((LayoutParams) p);
@@ -181,7 +380,7 @@
@Override
protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
- return p instanceof LayoutParams;
+ return p != null && p instanceof LayoutParams;
}
public LayoutParams generateOverflowButtonLayoutParams() {
@@ -224,6 +423,13 @@
public static class LayoutParams extends LinearLayout.LayoutParams {
@ViewDebug.ExportedProperty(category = "layout")
public boolean isOverflowButton;
+ @ViewDebug.ExportedProperty(category = "layout")
+ public int cellsUsed;
+ @ViewDebug.ExportedProperty(category = "layout")
+ public boolean multiCell;
+ @ViewDebug.ExportedProperty(category = "layout")
+ public int extraPixels;
+ public boolean expanded;
public LayoutParams(Context c, AttributeSet attrs) {
super(c, attrs);
diff --git a/core/java/com/android/internal/view/menu/MenuItemImpl.java b/core/java/com/android/internal/view/menu/MenuItemImpl.java
index 7b1dfb0..20b7d80 100644
--- a/core/java/com/android/internal/view/menu/MenuItemImpl.java
+++ b/core/java/com/android/internal/view/menu/MenuItemImpl.java
@@ -506,6 +506,10 @@
return mMenuInfo;
}
+ public void actionFormatChanged() {
+ mMenu.onItemActionRequestChanged(this);
+ }
+
/**
* @return Whether the menu should show icons for menu items.
*/
@@ -534,9 +538,7 @@
}
public boolean showsTextAsAction() {
- return (mShowAsAction & SHOW_AS_ACTION_WITH_TEXT) == SHOW_AS_ACTION_WITH_TEXT &&
- mMenu.getContext().getResources().getBoolean(
- com.android.internal.R.bool.allow_action_menu_item_text_with_icon);
+ return (mShowAsAction & SHOW_AS_ACTION_WITH_TEXT) == SHOW_AS_ACTION_WITH_TEXT;
}
public void setShowAsAction(int actionEnum) {
diff --git a/core/java/com/android/internal/widget/ActionBarContainer.java b/core/java/com/android/internal/widget/ActionBarContainer.java
index 953328c..9fef2a9 100644
--- a/core/java/com/android/internal/widget/ActionBarContainer.java
+++ b/core/java/com/android/internal/widget/ActionBarContainer.java
@@ -19,6 +19,8 @@
import android.app.ActionBar;
import android.content.Context;
import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.ActionMode;
import android.view.MotionEvent;
@@ -35,6 +37,12 @@
private View mTabContainer;
private ActionBarView mActionBarView;
+ private Drawable mBackground;
+ private Drawable mStackedBackground;
+ private Drawable mSplitBackground;
+ private boolean mIsSplit;
+ private boolean mIsStacked;
+
public ActionBarContainer(Context context) {
this(context, null);
}
@@ -42,10 +50,23 @@
public ActionBarContainer(Context context, AttributeSet attrs) {
super(context, attrs);
+ setBackgroundDrawable(null);
+
TypedArray a = context.obtainStyledAttributes(attrs,
com.android.internal.R.styleable.ActionBar);
- setBackgroundDrawable(a.getDrawable(com.android.internal.R.styleable.ActionBar_background));
+ mBackground = a.getDrawable(com.android.internal.R.styleable.ActionBar_background);
+ mStackedBackground = a.getDrawable(
+ com.android.internal.R.styleable.ActionBar_backgroundStacked);
+
+ if (getId() == com.android.internal.R.id.split_action_bar) {
+ mIsSplit = true;
+ mSplitBackground = a.getDrawable(
+ com.android.internal.R.styleable.ActionBar_backgroundSplit);
+ }
a.recycle();
+
+ setWillNotDraw(mIsSplit ? mSplitBackground == null :
+ mBackground == null && mStackedBackground == null);
}
@Override
@@ -96,6 +117,24 @@
}
@Override
+ public void onDraw(Canvas canvas) {
+ if (getWidth() == 0 || getHeight() == 0) {
+ return;
+ }
+
+ if (mIsSplit) {
+ if (mSplitBackground != null) mSplitBackground.draw(canvas);
+ } else {
+ if (mBackground != null) {
+ mBackground.draw(canvas);
+ }
+ if (mStackedBackground != null && mIsStacked) {
+ mStackedBackground.draw(canvas);
+ }
+ }
+ }
+
+ @Override
public ActionMode startActionModeForChild(View child, ActionMode.Callback callback) {
// No starting an action mode for an action bar child! (Where would it go?)
return null;
@@ -125,6 +164,9 @@
@Override
public void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
+
+ final boolean hasTabs = mTabContainer != null && mTabContainer.getVisibility() != GONE;
+
if (mTabContainer != null && mTabContainer.getVisibility() != GONE) {
final int containerHeight = getMeasuredHeight();
final int tabHeight = mTabContainer.getMeasuredHeight();
@@ -146,5 +188,28 @@
mTabContainer.layout(l, containerHeight - tabHeight, r, containerHeight);
}
}
+
+ boolean needsInvalidate = false;
+ if (mIsSplit) {
+ if (mSplitBackground != null) {
+ mSplitBackground.setBounds(0, 0, getMeasuredWidth(), getMeasuredHeight());
+ needsInvalidate = true;
+ }
+ } else {
+ if (mBackground != null) {
+ mBackground.setBounds(mActionBarView.getLeft(), mActionBarView.getTop(),
+ mActionBarView.getRight(), mActionBarView.getBottom());
+ needsInvalidate = true;
+ }
+ if ((mIsStacked = hasTabs && mStackedBackground != null)) {
+ mStackedBackground.setBounds(mTabContainer.getLeft(), mTabContainer.getTop(),
+ mTabContainer.getRight(), mTabContainer.getBottom());
+ needsInvalidate = true;
+ }
+ }
+
+ if (needsInvalidate) {
+ invalidate();
+ }
}
}
diff --git a/core/java/com/android/server/NetworkManagementSocketTagger.java b/core/java/com/android/server/NetworkManagementSocketTagger.java
index 306d223..2871073 100644
--- a/core/java/com/android/server/NetworkManagementSocketTagger.java
+++ b/core/java/com/android/server/NetworkManagementSocketTagger.java
@@ -30,6 +30,7 @@
public final class NetworkManagementSocketTagger extends SocketTagger {
private static final boolean LOGI = false;
+ private static final boolean ENABLE_TAGGING = false;
private static ThreadLocal<SocketTags> threadSocketTags = new ThreadLocal<SocketTags>() {
@Override protected SocketTags initialValue() {
@@ -124,6 +125,8 @@
*
*/
private void internalModuleCtrl(String cmd) throws IOException {
+ if (!ENABLE_TAGGING) return;
+
final FileOutputStream procOut;
// TODO: Use something like
// android.os.SystemProperties.getInt("persist.bandwidth.enable", 0)
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 1a32060..49eaf19 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1418,7 +1418,6 @@
android:label="@string/android_system_label"
android:allowClearUserData="false"
android:backupAgent="com.android.server.SystemBackupAgent"
- android:fullBackupAgent="com.android.server.SystemBackupAgent"
android:killAfterRestore="false"
android:icon="@drawable/ic_launcher_android">
<activity android:name="com.android.internal.app.ChooserActivity"
diff --git a/core/res/res/drawable-hdpi/ab_bottom_solid_dark_holo.9.png b/core/res/res/drawable-hdpi/ab_bottom_solid_dark_holo.9.png
new file mode 100644
index 0000000..3ea6c44
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ab_bottom_solid_dark_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ab_bottom_solid_inverse_holo.9.png b/core/res/res/drawable-hdpi/ab_bottom_solid_inverse_holo.9.png
new file mode 100644
index 0000000..6c6fcd2
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ab_bottom_solid_inverse_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ab_bottom_solid_light_holo.9.png b/core/res/res/drawable-hdpi/ab_bottom_solid_light_holo.9.png
new file mode 100644
index 0000000..854631e
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ab_bottom_solid_light_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ab_bottom_transparent_dark_holo.9.png b/core/res/res/drawable-hdpi/ab_bottom_transparent_dark_holo.9.png
new file mode 100644
index 0000000..aef6142d
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ab_bottom_transparent_dark_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ab_bottom_transparent_light_holo.9.png b/core/res/res/drawable-hdpi/ab_bottom_transparent_light_holo.9.png
new file mode 100644
index 0000000..d8b5edc
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ab_bottom_transparent_light_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ab_solid_dark_holo.9.png b/core/res/res/drawable-hdpi/ab_solid_dark_holo.9.png
new file mode 100644
index 0000000..660a234
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ab_solid_dark_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ab_solid_light_holo.9.png b/core/res/res/drawable-hdpi/ab_solid_light_holo.9.png
new file mode 100644
index 0000000..9756cf5
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ab_solid_light_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ab_solid_shadow_holo.9.png b/core/res/res/drawable-hdpi/ab_solid_shadow_holo.9.png
new file mode 100644
index 0000000..80213d5
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ab_solid_shadow_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ab_stacked_solid_dark_holo.9.png b/core/res/res/drawable-hdpi/ab_stacked_solid_dark_holo.9.png
new file mode 100644
index 0000000..6de2bf2c
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ab_stacked_solid_dark_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ab_stacked_solid_inverse_holo.9.png b/core/res/res/drawable-hdpi/ab_stacked_solid_inverse_holo.9.png
new file mode 100644
index 0000000..c23e473
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ab_stacked_solid_inverse_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ab_stacked_solid_light_holo.9.png b/core/res/res/drawable-hdpi/ab_stacked_solid_light_holo.9.png
new file mode 100644
index 0000000..343d7c6
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ab_stacked_solid_light_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ab_stacked_transparent_dark_holo.9.png b/core/res/res/drawable-hdpi/ab_stacked_transparent_dark_holo.9.png
new file mode 100644
index 0000000..3de1174
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ab_stacked_transparent_dark_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ab_stacked_transparent_light_holo.9.png b/core/res/res/drawable-hdpi/ab_stacked_transparent_light_holo.9.png
new file mode 100644
index 0000000..da8b042
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ab_stacked_transparent_light_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ab_transparent_dark_holo.9.png b/core/res/res/drawable-hdpi/ab_transparent_dark_holo.9.png
new file mode 100644
index 0000000..1957c32
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ab_transparent_dark_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ab_transparent_light_holo.9.png b/core/res/res/drawable-hdpi/ab_transparent_light_holo.9.png
new file mode 100644
index 0000000..0f1ce73
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ab_transparent_light_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ab_bottom_solid_dark_holo.9.png b/core/res/res/drawable-mdpi/ab_bottom_solid_dark_holo.9.png
new file mode 100644
index 0000000..3807a48
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ab_bottom_solid_dark_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ab_bottom_solid_inverse_holo.9.png b/core/res/res/drawable-mdpi/ab_bottom_solid_inverse_holo.9.png
new file mode 100644
index 0000000..9994438
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ab_bottom_solid_inverse_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ab_bottom_solid_light_holo.9.png b/core/res/res/drawable-mdpi/ab_bottom_solid_light_holo.9.png
new file mode 100644
index 0000000..5648403
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ab_bottom_solid_light_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ab_bottom_transparent_dark_holo.9.png b/core/res/res/drawable-mdpi/ab_bottom_transparent_dark_holo.9.png
new file mode 100644
index 0000000..261365d
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ab_bottom_transparent_dark_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ab_bottom_transparent_light_holo.9.png b/core/res/res/drawable-mdpi/ab_bottom_transparent_light_holo.9.png
new file mode 100644
index 0000000..95df5fc
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ab_bottom_transparent_light_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ab_solid_dark_holo.9.png b/core/res/res/drawable-mdpi/ab_solid_dark_holo.9.png
new file mode 100644
index 0000000..4a6c3bc
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ab_solid_dark_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ab_solid_light_holo.9.png b/core/res/res/drawable-mdpi/ab_solid_light_holo.9.png
new file mode 100644
index 0000000..93a0c3e
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ab_solid_light_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ab_solid_shadow_holo.9.png b/core/res/res/drawable-mdpi/ab_solid_shadow_holo.9.png
new file mode 100644
index 0000000..f3abd07
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ab_solid_shadow_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ab_stacked_solid_dark_holo.9.png b/core/res/res/drawable-mdpi/ab_stacked_solid_dark_holo.9.png
new file mode 100644
index 0000000..e1d8f67
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ab_stacked_solid_dark_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ab_stacked_solid_inverse_holo.9.png b/core/res/res/drawable-mdpi/ab_stacked_solid_inverse_holo.9.png
new file mode 100644
index 0000000..9d7e953
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ab_stacked_solid_inverse_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ab_stacked_solid_light_holo.9.png b/core/res/res/drawable-mdpi/ab_stacked_solid_light_holo.9.png
new file mode 100644
index 0000000..711e0fd
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ab_stacked_solid_light_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ab_stacked_transparent_dark_holo.9.png b/core/res/res/drawable-mdpi/ab_stacked_transparent_dark_holo.9.png
new file mode 100644
index 0000000..9649a2d
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ab_stacked_transparent_dark_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ab_stacked_transparent_light_holo.9.png b/core/res/res/drawable-mdpi/ab_stacked_transparent_light_holo.9.png
new file mode 100644
index 0000000..376e4ef
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ab_stacked_transparent_light_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ab_transparent_dark_holo.9.png b/core/res/res/drawable-mdpi/ab_transparent_dark_holo.9.png
new file mode 100644
index 0000000..99c8fd3
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ab_transparent_dark_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ab_transparent_light_holo.9.png b/core/res/res/drawable-mdpi/ab_transparent_light_holo.9.png
new file mode 100644
index 0000000..a86ec34
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ab_transparent_light_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ab_bottom_solid_dark_holo.9.png b/core/res/res/drawable-xhdpi/ab_bottom_solid_dark_holo.9.png
new file mode 100644
index 0000000..462e0e0
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ab_bottom_solid_dark_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ab_bottom_solid_inverse_holo.9.png b/core/res/res/drawable-xhdpi/ab_bottom_solid_inverse_holo.9.png
new file mode 100644
index 0000000..939ff4eb
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ab_bottom_solid_inverse_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ab_bottom_solid_light_holo.9.png b/core/res/res/drawable-xhdpi/ab_bottom_solid_light_holo.9.png
new file mode 100644
index 0000000..8f89040
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ab_bottom_solid_light_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ab_bottom_transparent_dark_holo.9.png b/core/res/res/drawable-xhdpi/ab_bottom_transparent_dark_holo.9.png
new file mode 100644
index 0000000..ccd53a3
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ab_bottom_transparent_dark_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ab_bottom_transparent_light_holo.9.png b/core/res/res/drawable-xhdpi/ab_bottom_transparent_light_holo.9.png
new file mode 100644
index 0000000..0b1ae2d
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ab_bottom_transparent_light_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ab_solid_dark_holo.9.png b/core/res/res/drawable-xhdpi/ab_solid_dark_holo.9.png
new file mode 100644
index 0000000..c8e5efc4
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ab_solid_dark_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ab_solid_light_holo.9.png b/core/res/res/drawable-xhdpi/ab_solid_light_holo.9.png
new file mode 100644
index 0000000..6cb8a0e
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ab_solid_light_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ab_solid_shadow_holo.9.png b/core/res/res/drawable-xhdpi/ab_solid_shadow_holo.9.png
new file mode 100644
index 0000000..49b2669
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ab_solid_shadow_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ab_stacked_solid_dark_holo.9.png b/core/res/res/drawable-xhdpi/ab_stacked_solid_dark_holo.9.png
new file mode 100644
index 0000000..201e21d
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ab_stacked_solid_dark_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ab_stacked_solid_inverse_holo.9.png b/core/res/res/drawable-xhdpi/ab_stacked_solid_inverse_holo.9.png
new file mode 100644
index 0000000..ac96200
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ab_stacked_solid_inverse_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ab_stacked_solid_light_holo.9.png b/core/res/res/drawable-xhdpi/ab_stacked_solid_light_holo.9.png
new file mode 100644
index 0000000..d605d96
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ab_stacked_solid_light_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ab_stacked_transparent_dark_holo.9.png b/core/res/res/drawable-xhdpi/ab_stacked_transparent_dark_holo.9.png
new file mode 100644
index 0000000..8ece2a9
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ab_stacked_transparent_dark_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ab_stacked_transparent_light_holo.9.png b/core/res/res/drawable-xhdpi/ab_stacked_transparent_light_holo.9.png
new file mode 100644
index 0000000..ae0b6b7
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ab_stacked_transparent_light_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ab_transparent_dark_holo.9.png b/core/res/res/drawable-xhdpi/ab_transparent_dark_holo.9.png
new file mode 100644
index 0000000..d3a3809
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ab_transparent_dark_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ab_transparent_light_holo.9.png b/core/res/res/drawable-xhdpi/ab_transparent_light_holo.9.png
new file mode 100644
index 0000000..7e6e24d
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ab_transparent_light_holo.9.png
Binary files differ
diff --git a/core/res/res/layout/action_menu_item_layout.xml b/core/res/res/layout/action_menu_item_layout.xml
index a8f0c22..dca6c52 100644
--- a/core/res/res/layout/action_menu_item_layout.xml
+++ b/core/res/res/layout/action_menu_item_layout.xml
@@ -21,8 +21,8 @@
android:addStatesFromChildren="true"
android:gravity="center"
android:focusable="true"
- android:paddingLeft="12dip"
- android:paddingRight="12dip"
+ android:paddingLeft="4dip"
+ android:paddingRight="4dip"
style="?android:attr/actionButtonStyle">
<ImageButton android:id="@+id/imageButton"
android:layout_width="wrap_content"
@@ -45,6 +45,8 @@
android:textAppearance="?attr/actionMenuTextAppearance"
style="?attr/buttonStyleSmall"
android:textColor="?attr/actionMenuTextColor"
+ android:singleLine="true"
+ android:ellipsize="none"
android:background="@null"
android:paddingTop="4dip"
android:paddingBottom="4dip"
diff --git a/core/res/res/values-w480dp/bools.xml b/core/res/res/values-w480dp/bools.xml
index 8206e79..57a2939 100644
--- a/core/res/res/values-w480dp/bools.xml
+++ b/core/res/res/values-w480dp/bools.xml
@@ -17,7 +17,6 @@
*/
-->
<resources>
- <bool name="allow_action_menu_item_text_with_icon">true</bool>
<bool name="action_bar_embed_tabs">true</bool>
<bool name="split_action_bar_is_narrow">false</bool>
</resources>
diff --git a/core/res/res/values-w480dp/config.xml b/core/res/res/values-w480dp/config.xml
new file mode 100644
index 0000000..269a9b4
--- /dev/null
+++ b/core/res/res/values-w480dp/config.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** 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.
+*/
+-->
+<resources>
+ <bool name="config_allowActionMenuItemTextWithIcon">true</bool>
+</resources>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index aa8c510..b92ce6a 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -5210,6 +5210,10 @@
<attr name="divider" />
<!-- Specifies a background drawable for the action bar. -->
<attr name="background" />
+ <!-- Specifies a background drawable for a second stacked row of the action bar. -->
+ <attr name="backgroundStacked" format="reference" />
+ <!-- Specifies a background drawable for the bottom component of a split action bar. -->
+ <attr name="backgroundSplit" format="reference" />
<!-- Specifies a layout for custom navigation. Overrides navigationMode. -->
<attr name="customNavigationLayout" format="reference" />
<!-- Specifies a fixed height. -->
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 03b332e..dd16bd0 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -696,13 +696,6 @@
<p>The default value of this attribute is <code>false</code>. -->
<attr name="restoreAnyVersion" format="boolean" />
- <!-- The agent to use for a *full* backup of the package. Only system applications
- can use this to override the ordinary FullBackupAgent with a custom implementation.
- It's needed strictly for packages with strongly device-specific data, such as the
- Settings provider.
- -->
- <attr name="fullBackupAgent" format="string" />
-
<!-- The default install location defined by an application. -->
<attr name="installLocation">
<!-- Let the system decide ideal install location -->
@@ -800,7 +793,6 @@
<attr name="killAfterRestore" />
<attr name="restoreNeedsApplication" />
<attr name="restoreAnyVersion" />
- <attr name="fullBackupAgent" />
<attr name="neverEncrypt" />
<!-- Request that your application's processes be created with
a large Dalvik heap. This applies to <em>all</em> processes
diff --git a/core/res/res/values/bools.xml b/core/res/res/values/bools.xml
index 9647bb7..e51fc66 100644
--- a/core/res/res/values/bools.xml
+++ b/core/res/res/values/bools.xml
@@ -15,7 +15,6 @@
-->
<resources>
- <bool name="allow_action_menu_item_text_with_icon">false</bool>
<bool name="action_bar_embed_tabs">false</bool>
<bool name="split_action_bar_is_narrow">true</bool>
<bool name="preferences_prefer_dual_pane">false</bool>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 87b9be4..9f05cbc 100755
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -650,4 +650,14 @@
autodetected from the Configuration. -->
<bool name="config_showNavigationBar">false</bool>
+ <!-- Whether action menu items should be displayed in ALLCAPS or not.
+ Defaults to true. If this is not appropriate for specific locales
+ it should be disabled in that locale's resources. -->
+ <bool name="config_actionMenuItemAllCaps">true</bool>
+
+ <!-- Whether action menu items should obey the "withText" showAsAction
+ flag. This may be set to false for situations where space is
+ extremely limited. -->
+ <bool name="config_allowActionMenuItemTextWithIcon">false</bool>
+
</resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 54e484e..75acb37 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1714,10 +1714,6 @@
<public type="attr" name="switchTextOff" />
<public type="attr" name="switchPreferenceStyle" />
- <public type="style" name="TextAppearance.SuggestionHighlight" />
- <public type="style" name="Theme.Holo.SplitActionBarWhenNarrow" />
- <public type="style" name="Theme.Holo.Light.SplitActionBarWhenNarrow" />
-
<public type="attr" name="textSuggestionsWindowStyle" />
<public type="attr" name="textEditSuggestionsBottomWindowLayout" />
<public type="attr" name="textEditSuggestionsTopWindowLayout" />
@@ -1725,7 +1721,6 @@
<public type="attr" name="layoutDirection" />
- <public type="attr" name="fullBackupAgent" />
<public type="attr" name="suggestionsEnabled" />
<public type="attr" name="rowCount" />
@@ -1737,7 +1732,6 @@
<public type="attr" name="layout_row" />
<public type="attr" name="layout_rowSpan" />
-
<public type="attr" name="layout_columnSpan" />
<public type="attr" name="layout_widthSpec" />
@@ -1778,14 +1772,38 @@
<public type="attr" name="actionBarSplitStyle" />
- <public type="style" name="Widget.Holo.Button.Borderless.Small" />
- <public type="style" name="Widget.Holo.Light.Button.Borderless.Small" />
-
- <public type="integer" name="status_bar_notification_info_maxnum" />
- <public type="string" name="status_bar_notification_info_overflow" />
-
<public type="attr" name="textDirection"/>
<public type="attr" name="actionProviderClass" />
+ <public type="attr" name="backgroundStacked" />
+ <public type="attr" name="backgroundSplit" />
+
+ <public type="style" name="TextAppearance.SuggestionHighlight" />
+ <public type="style" name="Theme.Holo.SplitActionBarWhenNarrow" />
+ <public type="style" name="Theme.Holo.Light.SplitActionBarWhenNarrow" />
+
+ <public type="style" name="Widget.Holo.Button.Borderless.Small" />
+ <public type="style" name="Widget.Holo.Light.Button.Borderless.Small" />
+ <public type="style" name="TextAppearance.Holo.Widget.ActionBar.Title.Inverse" />
+ <public type="style" name="TextAppearance.Holo.Widget.ActionBar.Subtitle.Inverse" />
+ <public type="style" name="TextAppearance.Holo.Widget.ActionMode.Title.Inverse" />
+ <public type="style" name="TextAppearance.Holo.Widget.ActionMode.Subtitle.Inverse" />
+ <public type="style" name="Widget.Holo.ActionBar.Solid" />
+ <public type="style" name="Widget.Holo.Light.ActionBar.Solid" />
+ <public type="style" name="Widget.Holo.Light.ActionBar.Solid.Inverse" />
+ <public type="style" name="Widget.Holo.Light.ActionBar.TabBar.Inverse" />
+ <public type="style" name="Widget.Holo.Light.ActionBar.TabView.Inverse" />
+ <public type="style" name="Widget.Holo.Light.ActionBar.TabText.Inverse" />
+ <public type="style" name="Widget.Holo.Light.ActionMode.Inverse" />
+ <public type="style" name="Theme.Holo.SolidActionBar" />
+ <public type="style" name="Theme.Holo.Light.SolidActionBar" />
+ <public type="style" name="Theme.Holo.Light.SolidActionBar.Inverse" />
+ <public type="style" name="Theme.Holo.SolidActionBar.SplitActionBarWhenNarrow" />
+ <public type="style" name="Theme.Holo.Light.SolidActionBar.SplitActionBarWhenNarrow" />
+ <public type="style" name="Theme.Holo.Light.SolidActionBar.Inverse.SplitActionBarWhenNarrow" />
+
+ <public type="integer" name="status_bar_notification_info_maxnum" />
+ <public type="string" name="status_bar_notification_info_overflow" />
+
</resources>
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 5244b74..9ee4b6a 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -1304,13 +1304,37 @@
<item name="android:textSize">@android:dimen/action_bar_subtitle_text_size</item>
</style>
+ <style name="TextAppearance.Holo.Widget.ActionBar.Title.Inverse"
+ parent="TextAppearance.Holo.Medium.Inverse">
+ <item name="android:textSize">@android:dimen/action_bar_title_text_size</item>
+ </style>
+
+ <style name="TextAppearance.Holo.Widget.ActionBar.Subtitle.Inverse"
+ parent="TextAppearance.Holo.Small.Inverse">
+ <item name="android:textSize">@android:dimen/action_bar_subtitle_text_size</item>
+ </style>
+
<style name="TextAppearance.Holo.Widget.ActionMode">
</style>
- <style name="TextAppearance.Holo.Widget.ActionMode.Title" parent="TextAppearance.Widget.ActionMode.Title">
+ <style name="TextAppearance.Holo.Widget.ActionMode.Title"
+ parent="TextAppearance.Holo.Medium">
+ <item name="android:textSize">@android:dimen/action_bar_title_text_size</item>
</style>
- <style name="TextAppearance.Holo.Widget.ActionMode.Subtitle" parent="TextAppearance.Widget.ActionMode.Subtitle">
+ <style name="TextAppearance.Holo.Widget.ActionMode.Subtitle"
+ parent="TextAppearance.Holo.Small">
+ <item name="android:textSize">@android:dimen/action_bar_subtitle_text_size</item>
+ </style>
+
+ <style name="TextAppearance.Holo.Widget.ActionMode.Title.Inverse"
+ parent="TextAppearance.Holo.Medium.Inverse">
+ <item name="android:textSize">@android:dimen/action_bar_title_text_size</item>
+ </style>
+
+ <style name="TextAppearance.Holo.Widget.ActionMode.Subtitle.Inverse"
+ parent="TextAppearance.Holo.Small.Inverse">
+ <item name="android:textSize">@android:dimen/action_bar_subtitle_text_size</item>
</style>
<style name="TextAppearance.Holo.Widget.Switch" parent="TextAppearance.Holo.Small">
@@ -1839,7 +1863,22 @@
<style name="Widget.Holo.ActionBar" parent="Widget.ActionBar">
<item name="android:titleTextStyle">@android:style/TextAppearance.Holo.Widget.ActionBar.Title</item>
<item name="android:subtitleTextStyle">@android:style/TextAppearance.Holo.Widget.ActionBar.Subtitle</item>
- <item name="android:background">@null</item>
+ <item name="android:background">@android:drawable/ab_transparent_dark_holo</item>
+ <item name="android:backgroundStacked">@android:drawable/ab_stacked_transparent_dark_holo</item>
+ <item name="android:backgroundSplit">@android:drawable/ab_bottom_transparent_dark_holo</item>
+ <item name="android:divider">?android:attr/dividerVertical</item>
+ <item name="android:progressBarStyle">@android:style/Widget.Holo.ProgressBar.Horizontal</item>
+ <item name="android:indeterminateProgressStyle">@android:style/Widget.Holo.ProgressBar</item>
+ <item name="android:progressBarPadding">32dip</item>
+ <item name="android:itemPadding">8dip</item>
+ </style>
+
+ <style name="Widget.Holo.ActionBar.Solid">
+ <item name="android:titleTextStyle">@android:style/TextAppearance.Holo.Widget.ActionBar.Title</item>
+ <item name="android:subtitleTextStyle">@android:style/TextAppearance.Holo.Widget.ActionBar.Subtitle</item>
+ <item name="android:background">@android:drawable/ab_solid_dark_holo</item>
+ <item name="android:backgroundStacked">@android:drawable/ab_stacked_solid_dark_holo</item>
+ <item name="android:backgroundSplit">@android:drawable/ab_bottom_solid_dark_holo</item>
<item name="android:divider">?android:attr/dividerVertical</item>
<item name="android:progressBarStyle">@android:style/Widget.Holo.ProgressBar.Horizontal</item>
<item name="android:indeterminateProgressStyle">@android:style/Widget.Holo.ProgressBar</item>
@@ -2157,23 +2196,68 @@
<style name="Widget.Holo.Light.ActionBar.TabText" parent="Widget.Holo.ActionBar.TabText">
</style>
+ <style name="Widget.Holo.Light.ActionBar.TabView.Inverse">
+ </style>
+
+ <style name="Widget.Holo.Light.ActionBar.TabBar.Inverse">
+ </style>
+
+ <style name="Widget.Holo.Light.ActionBar.TabText.Inverse">
+ <item name="android:textAppearance">@style/TextAppearance.Holo.Medium</item>
+ <item name="android:textColor">?android:attr/textColorPrimaryInverse</item>
+ <item name="android:textSize">18sp</item>
+ </style>
+
<style name="Widget.Holo.Light.ActionMode" parent="Widget.Holo.ActionMode">
<item name="android:titleTextStyle">@android:style/TextAppearance.Holo.Widget.ActionMode.Title</item>
<item name="android:subtitleTextStyle">@android:style/TextAppearance.Holo.Widget.ActionMode.Subtitle</item>
</style>
+ <style name="Widget.Holo.Light.ActionMode.Inverse" parent="Widget.ActionMode">
+ <item name="android:titleTextStyle">@android:style/TextAppearance.Holo.Widget.ActionMode.Title.Inverse</item>
+ <item name="android:subtitleTextStyle">@android:style/TextAppearance.Holo.Widget.ActionMode.Subtitle.Inverse</item>
+ </style>
+
<style name="Widget.Holo.Light.ActionButton.CloseMode">
</style>
<style name="Widget.Holo.Light.ActionBar" parent="Widget.Holo.ActionBar">
<item name="android:titleTextStyle">@android:style/TextAppearance.Holo.Widget.ActionBar.Title</item>
<item name="android:subtitleTextStyle">@android:style/TextAppearance.Holo.Widget.ActionBar.Subtitle</item>
- <item name="android:background">@null</item>
+ <item name="android:background">@android:drawable/ab_transparent_light_holo</item>
+ <item name="android:backgroundStacked">@android:drawable/ab_stacked_transparent_light_holo</item>
+ <item name="android:backgroundSplit">@android:drawable/ab_bottom_transparent_light_holo</item>
<item name="android:homeAsUpIndicator">@android:drawable/ic_ab_back_holo_light</item>
<item name="android:progressBarStyle">@android:style/Widget.Holo.Light.ProgressBar.Horizontal</item>
<item name="android:indeterminateProgressStyle">@android:style/Widget.Holo.Light.ProgressBar</item>
</style>
+ <style name="Widget.Holo.Light.ActionBar.Solid">
+ <item name="android:titleTextStyle">@android:style/TextAppearance.Holo.Widget.ActionBar.Title</item>
+ <item name="android:subtitleTextStyle">@android:style/TextAppearance.Holo.Widget.ActionBar.Subtitle</item>
+ <item name="android:background">@android:drawable/ab_solid_light_holo</item>
+ <item name="android:backgroundStacked">@android:drawable/ab_stacked_solid_light_holo</item>
+ <item name="android:backgroundSplit">@android:drawable/ab_bottom_solid_light_holo</item>
+ <item name="android:divider">?android:attr/dividerVertical</item>
+ <item name="android:progressBarStyle">@android:style/Widget.Holo.Light.ProgressBar.Horizontal</item>
+ <item name="android:indeterminateProgressStyle">@android:style/Widget.Holo.Light.ProgressBar</item>
+ <item name="android:progressBarPadding">32dip</item>
+ <item name="android:itemPadding">8dip</item>
+ </style>
+
+ <style name="Widget.Holo.Light.ActionBar.Solid.Inverse">
+ <item name="android:titleTextStyle">@android:style/TextAppearance.Holo.Widget.ActionBar.Title.Inverse</item>
+ <item name="android:subtitleTextStyle">@android:style/TextAppearance.Holo.Widget.ActionBar.Subtitle.Inverse</item>
+ <item name="android:background">@android:drawable/ab_solid_dark_holo</item>
+ <item name="android:backgroundStacked">@android:drawable/ab_stacked_solid_dark_holo</item>
+ <item name="android:backgroundSplit">@android:drawable/ab_bottom_solid_inverse_holo</item>
+ <item name="android:divider">@android:drawable/list_divider_holo_dark</item>
+ <item name="android:progressBarStyle">@android:style/Widget.Holo.ProgressBar.Horizontal</item>
+ <item name="android:indeterminateProgressStyle">@android:style/Widget.Holo.ProgressBar</item>
+ <item name="android:progressBarPadding">32dip</item>
+ <item name="android:itemPadding">8dip</item>
+ </style>
+
<!-- Animation Styles -->
<style name="Animation.Holo" parent="Animation">
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index 78e9975..23111e6 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -283,7 +283,7 @@
<item name="actionBarSplitStyle">?android:attr/actionBarStyle</item>
<item name="actionBarSize">@dimen/action_bar_default_height</item>
<item name="actionModePopupWindowStyle">?android:attr/popupWindowStyle</item>
- <item name="actionMenuTextAppearance">?android:attr/textAppearanceMedium</item>
+ <item name="actionMenuTextAppearance">?android:attr/textAppearanceSmall</item>
<item name="actionMenuTextColor">?android:attr/textColorPrimary</item>
<item name="dividerVertical">@drawable/divider_vertical_dark</item>
@@ -1365,6 +1365,71 @@
</style>
+ <!-- Variant of the holographic (dark) theme that has a solid (opaque) action bar. -->
+ <style name="Theme.Holo.SolidActionBar">
+ <item name="android:actionBarStyle">@android:style/Widget.Holo.ActionBar.Solid</item>
+ <item name="android:windowContentOverlay">@android:drawable/ab_solid_shadow_holo</item>
+ </style>
+
+ <!-- Variant of the holographic (light) theme that has a solid (opaque) action bar. -->
+ <style name="Theme.Holo.Light.SolidActionBar">
+ <item name="android:actionBarStyle">@android:style/Widget.Holo.Light.ActionBar.Solid</item>
+ <item name="android:windowContentOverlay">@android:drawable/ab_solid_shadow_holo</item>
+ </style>
+
+ <!-- Variant of the holographic (light) theme that has a solid (opaque) action bar
+ with an inverse color profile. The dark action bar sharply stands out against
+ the light content. -->
+ <style name="Theme.Holo.Light.SolidActionBar.Inverse">
+ <item name="android:windowContentOverlay">@android:drawable/title_bar_shadow</item>
+ <item name="android:actionBarStyle">@android:style/Widget.Holo.Light.ActionBar.Solid.Inverse</item>
+
+ <item name="actionDropDownStyle">@android:style/Widget.Holo.Spinner.DropDown.ActionBar</item>
+ <item name="actionButtonStyle">@android:style/Widget.Holo.ActionButton</item>
+ <item name="actionOverflowButtonStyle">@android:style/Widget.Holo.ActionButton.Overflow</item>
+ <item name="actionModeBackground">@android:drawable/cab_background_holo_dark</item>
+ <item name="actionModeCloseDrawable">@android:drawable/cab_ic_close_holo</item>
+ <item name="actionBarTabStyle">@style/Widget.Holo.Light.ActionBar.TabView.Inverse</item>
+ <item name="actionBarTabBarStyle">@style/Widget.Holo.Light.ActionBar.TabBar.Inverse</item>
+ <item name="actionBarTabTextStyle">@style/Widget.Holo.Light.ActionBar.TabText.Inverse</item>
+ <item name="actionMenuTextColor">?android:attr/textColorPrimaryInverse</item>
+ <item name="actionModeStyle">@style/Widget.Holo.Light.ActionMode.Inverse</item>
+ <item name="actionModeCloseButtonStyle">@style/Widget.Holo.ActionButton.CloseMode</item>
+ <item name="actionModePopupWindowStyle">@android:style/Widget.Holo.PopupWindow.ActionMode</item>
+
+ <item name="actionModeCutDrawable">@android:drawable/ic_menu_cut_holo_dark</item>
+ <item name="actionModeCopyDrawable">@android:drawable/ic_menu_copy_holo_dark</item>
+ <item name="actionModePasteDrawable">@android:drawable/ic_menu_paste_holo_dark</item>
+ <item name="actionModeSelectAllDrawable">@android:drawable/ic_menu_selectall_holo_dark</item>
+ <item name="actionModeShareDrawable">@android:drawable/ic_menu_share_holo_dark</item>
+ <item name="actionModeFindDrawable">@android:drawable/ic_menu_find_holo_dark</item>
+ <item name="actionModeWebSearchDrawable">@android:drawable/ic_menu_search_holo_dark</item>
+ </style>
+
+ <!-- Variant of the holographic (dark) theme that has a solid
+ (opaque) action bar. The action bar will split across both
+ the top and bottom of the screen when the screen is
+ especially constrained for horizontal space. -->
+ <style name="Theme.Holo.SolidActionBar.SplitActionBarWhenNarrow">
+ <item name="android:windowSplitActionBar">@android:bool/split_action_bar_is_narrow</item>
+ </style>
+
+ <!-- Variant of the holographic (light) theme that has a solid
+ (opaque) action bar. The action bar will split across both
+ the top and bottom of the screen when the screen is
+ especially constrained for horizontal space. -->
+ <style name="Theme.Holo.Light.SolidActionBar.SplitActionBarWhenNarrow">
+ <item name="android:windowSplitActionBar">@android:bool/split_action_bar_is_narrow</item>
+ </style>
+
+ <!-- Variant of the holographic (light) theme that has a solid (opaque) action bar
+ with an inverse color profile. The dark action bar sharply stands out against
+ the light content. The action bar will split across both the top and bottom of
+ the screen when the screen is especially constrained for horizontal space. -->
+ <style name="Theme.Holo.Light.SolidActionBar.Inverse.SplitActionBarWhenNarrow">
+ <item name="android:windowSplitActionBar">@android:bool/split_action_bar_is_narrow</item>
+ </style>
+
<!-- Variant of the holographic (dark) theme with no action bar. -->
<style name="Theme.Holo.NoActionBar">
<item name="android:windowActionBar">false</item>
diff --git a/docs/html/guide/publishing/publishing.jd b/docs/html/guide/publishing/publishing.jd
index 0cbba53..95d89fa 100644
--- a/docs/html/guide/publishing/publishing.jd
+++ b/docs/html/guide/publishing/publishing.jd
@@ -23,6 +23,7 @@
<ol>
<li><a href="#OpeningDetails">Opening an app's details page</a></li>
<li><a href="#PerformingSearch">Performing a search</a></li>
+ <li><a href="#BuildaButton">Build an Android Market button</a></li>
<li><a href="#UriSummary">Summary of URI formats</a></li>
</ol>
</li>
@@ -317,6 +318,205 @@
+<h3 id="BuildaButton">Build an Android Market button</h3>
+
+<p>Use the following form to input either your application's package name or your publisher name
+and generate a button that you can use on your web site. The button will take users to Android
+Market to view your application details or view a list of all applications you've published.</p>
+
+<p>This form offers four versions of the official "Available in Android Market" badge at
+recommended sizes. If you would like to create a different size, you can download an EPS file for
+the badges from the <a href="http://www.android.com/branding.html">Android Brand Guidelines</a>.</p>
+
+<style type="text/css">
+
+form.button-form {
+ margin-top:2em;
+}
+
+/* the label and input elements are blocks that float left in order to
+ keep the left edgets of the input aligned, and IE 6/7 do not fully support "inline-block" */
+label.block {
+ display: block;
+ float: left;
+ width: 100px;
+ padding-right: 10px;
+}
+
+input.text {
+ display: block;
+ float: left;
+ width: 250px;
+}
+
+div.button-row {
+ white-space:nowrap;
+ min-height:80px;
+}
+
+div.button-row input {
+ vertical-align:120%;
+}
+
+#jd-content div.button-row img {
+ margin: 0;
+}
+
+</style>
+
+<script type="text/javascript">
+
+// variables for creating 'try it out' demo button
+var imagePath = "http://www.android.com/images/brand/"
+var linkStart = "<a href=\"http://market.android.com/";
+var imageStart = "\">\n"
+ + " <img src=\"" + imagePath;
+var imageEnd = ".png\"\n"
+ + " alt=\"Available in Android Market\" />\n</a>";
+
+// variables for creating code snippet
+var linkStartCode = "<a href=\"http://market.android.com/";
+var imageStartCode = "\">\n"
+ + " <img src=\"" + imagePath;
+var imageEndCode = ".png\"\n"
+ + " alt=\"Available in Android Market\" />\n</a>";
+
+/** Generate the HTML snippet and demo based on form values */
+function buildButton(form) {
+ if (form["package"].value != "com.android.example") {
+ $("#preview").show();
+ $("#snippet").show().html(linkStartCode + "details?id=" + form["package"].value
+ + imageStartCode + $('form input[type=radio]:checked').val() + imageEndCode);
+ $("#button-preview").html(linkStart + "details?id=" + form["package"].value
+ + imageStart + $('form input[type=radio]:checked').val() + imageEnd);
+ } else if (form["publisher"].value != "Example, Inc.") {
+ $("#preview").show();
+ $("#snippet").show().html(linkStartCode + "search?q=pub:" + form["publisher"].value
+ + imageStartCode + $('form input[type=radio]:checked').val() + imageEndCode);
+ $("#button-preview").html(linkStart + "search?q=pub:" + form["publisher"].value + imageStart +
+ $('form input[type=radio]:checked').val() + imageEnd);
+ } else {
+ alert("Please enter your package name or publisher name");
+ }
+ return false;
+}
+
+/** Listen for Enter key */
+function onTextEntered(event, form, me) {
+ // 13 = enter
+ if (event.keyCode == 13) {
+ buildButton(form);
+ }
+}
+
+/** When input is focused, remove example text and disable other input */
+function onInputFocus(object, example) {
+ if (object.value == example) {
+ $(object).val('').css({'color' : '#000'});
+ }
+ $('input[type="text"]:not(input[name='+object.name+'])',
+ object.parentNode).attr('disabled','true');
+ $('#'+object.name+'-clear').show();
+}
+
+/** When input is blured, restore example text if appropriate and enable other input */
+function onInputBlur(object, example) {
+ if (object.value.length < 1) {
+ $(object).attr('value',example).css({'color':'#ccc'});
+ $('input[type="text"]', object.parentNode).removeAttr('disabled');
+ $('#'+object.name+'-clear').hide();
+ }
+}
+
+/** Clear the form to start over */
+function clearLabel(id, example) {
+ $("#preview").hide();
+ $('#'+id+'').html('').attr('value',example).css({'color':'#ccc'});
+ $('input[type="text"]', $('#'+id+'').parent()).removeAttr('disabled');
+ $('#'+id+'-clear').hide();
+ return false;
+}
+
+/** When the doc is ready, find the inputs and color the input grey if the value is the example
+ text. This is necessary to handle back-navigation, which can auto-fill the form with previous
+ values (and text should not be grey) */
+$(document).ready(function() {
+ $(".button-form input.text").each(function(index) {
+ if ($(this).val() == $(this).attr("default")) {
+ $(this).css("color","#ccc");
+ } else {
+ /* This is necessary to handle back-navigation to the page after form was filled */
+ $('input[type="text"]:not(input[name='+this.name+'])',
+ this.parentNode).attr('disabled','true');
+ $('#'+this.name+'-clear').show();
+ }
+ });
+});
+
+</script>
+
+<form class="button-form">
+ <label class="block" for="package">Package name:</label>
+ <input class="text" type="text" id="package" name="package"
+ value="com.android.example"
+ default="com.android.example"
+ onfocus="onInputFocus(this, 'com.android.example')"
+ onblur="onInputBlur(this, 'com.android.example')"
+ onkeyup="return onTextEntered(event, this.parentNode, this)"/>
+ <a id="package-clear" style="display:none" href="#"
+ onclick="return clearLabel('package','com.android.example');">clear</a>
+ <p style="clear:both;margin:0"> <em>or</em></p>
+ <label class="block" style="margin-top:5px" for="publisher">Publisher name:</label>
+ <input class="text" type="text" id="publisher" name="publisher"
+ value="Example, Inc."
+ default="Example, Inc."
+ onfocus="onInputFocus(this, 'Example, Inc.')"
+ onblur="onInputBlur(this, 'Example, Inc.')"
+ onkeyup="return onTextEntered(event, this.parentNode, this)"/>
+ <a id="publisher-clear" style="display:none" href="#"
+ onclick="return clearLabel('publisher','Example, Inc.');">clear</a>
+ <br/><br/>
+
+<div class="button-row">
+ <input type="radio" name="buttonStyle" value="45_avail_market_logo1" id="ns" checked="checked" />
+ <label for="ns"><img src="http://www.android.com/images/brand/45_avail_market_logo1.png"
+alt="narrow and small logo" /></label>
+
+ <input type="radio" name="buttonStyle" value="60_avail_market_logo1" id="nm" />
+ <label for="nm"><img src="http://www.android.com/images/brand/60_avail_market_logo1.png"
+alt="narrow and large logo" /></label>
+</div>
+
+<div class="button-row">
+ <input type="radio" name="buttonStyle" value="45_avail_market_logo2" id="ws" />
+ <label for="ws"><img src="http://www.android.com/images/brand/45_avail_market_logo2.png"
+alt="wide and small logo" /></label>
+
+ <input type="radio" name="buttonStyle" value="60_avail_market_logo2" id="wm" />
+ <label for="wm"><img src="http://www.android.com/images/brand/60_avail_market_logo2.png"
+alt="wide and large logo" /></label>
+</div>
+
+ <input type="button" onclick="return buildButton(this.parentNode)" value="Build my button"
+style="padding:5px" />
+ <br/>
+</form>
+
+<div id="preview" style="display:none">
+ <p>Copy and paste this HTML into your web site:</p>
+ <textarea id="snippet" cols="80" rows="4" onclick="this.select()"
+style="font-family:monospace;background-color:#efefef;padding:5px;display:none;margin-bottom:1em">
+ </textarea >
+
+<p>Try it out:</p>
+<div id="button-preview" style="margin-top:1em"></div>
+</div>
+
+
+
+
+
+
<h3 id="UriSummary">Summary of URI formats</h3>
<p>The table below provides a summary of the URIs currently supported by the Android Market (both on
diff --git a/docs/html/resources/dashboard/opengl.jd b/docs/html/resources/dashboard/opengl.jd
index dac8ce5..3fcfa89 100644
--- a/docs/html/resources/dashboard/opengl.jd
+++ b/docs/html/resources/dashboard/opengl.jd
@@ -57,7 +57,7 @@
<div class="dashboard-panel">
<img alt="" width="400" height="250"
-src="http://chart.googleapis.com/chart?cht=p&chs=400x250&chco=c4df9b,6fad0c&chl=GL%20ES%201.1|GL%20ES%202.0&chd=t%3A8.9,91.1" />
+src="http://chart.googleapis.com/chart?cht=p&chs=400x250&chco=c4df9b,6fad0c&chl=GL%201.1|GL%202.0%20%26%201.1&chd=t%3A8.9,91" />
<table>
<tr>
@@ -66,11 +66,11 @@
</tr>
<tr>
<td>1.1</th>
-<td>8.9%</td>
+<td>9%</td>
</tr>
<tr>
<td>2.0</th>
-<td>91.1%</td>
+<td>91%</td>
</tr>
</table>
diff --git a/docs/html/resources/dashboard/platform-versions.jd b/docs/html/resources/dashboard/platform-versions.jd
index 368164d..d9adb36 100644
--- a/docs/html/resources/dashboard/platform-versions.jd
+++ b/docs/html/resources/dashboard/platform-versions.jd
@@ -51,8 +51,8 @@
<div class="dashboard-panel">
-<img alt="" height="250" width="460"
-src="http://chart.apis.google.com/chart?&cht=p&chs=460x250&chd=t:2.3,3.0,24.5,65.9,1.0,3.0,0.3&chl=Android%201.5|Android%201.6|Android%202.1|Android%202.2|Android%202.3|Android%202.3.3|Android%203.0&chco=c4df9b,6fad0c" />
+<img alt="" height="250" width="470"
+src="http://chart.apis.google.com/chart?&cht=p&chs=460x250&chd=t:1.4,2.2,17.5,59.4,1.0,17.6,0.4,0.5&chl=Android%201.5|Android%201.6|Android%202.1|Android%202.2|Android%202.3%20-%202.3.2|Android%202.3.3%20-%202.3.4|Android%203.0|Android%203.1&chco=c4df9b,6fad0c" />
<table>
<tr>
@@ -60,16 +60,19 @@
<th>API Level</th>
<th>Distribution</th>
</tr>
-<tr><td>Android 1.5</td><td>3</td><td>2.3%</td></tr>
-<tr><td>Android 1.6</td><td>4</td><td>3.0%</td></tr>
-<tr><td>Android 2.1</td><td>7</td><td>24.5%</td></tr>
-<tr><td>Android 2.2</td><td>8</td><td>65.9%</td></tr>
-<tr><td>Android 2.3</td><td>9</td><td>1.0%</td></tr>
-<tr><td>Android 2.3.3</td><td>10</td><td>3.0%</td></tr>
-<tr><td>Android 3.0</td><td>11</td><td>0.3%</td></tr>
+<tr><td>Android 1.5</td><td>3</td><td>1.4%</td></tr>
+<tr><td>Android 1.6</td><td>4</td><td>2.2%</td></tr>
+<tr><td>Android 2.1</td><td>7</td><td>17.5%</td></tr>
+<tr><td>Android 2.2</td><td>8</td><td>59.4%</td></tr>
+<tr><td>Android 2.3 -<br/>
+ Android 2.3.2</td><td>9</td><td>1%</td></tr>
+<tr><td>Android 2.3.3 -<br/>
+ Android 2.3.4</td><td>10</td><td>17.6%</td></tr>
+<tr><td>Android 3.0</td><td>11</td><td>0.4%</td></tr>
+<tr><td>Android 3.1</td><td>12</td><td>0.5%</td></tr>
</table>
-<p><em>Data collected during two weeks ending on May 2, 2011</em></p>
+<p><em>Data collected during a 14-day period ending on July 5, 2011</em></p>
<!--
<p style="font-size:.9em">* <em>Other: 0.1% of devices running obsolete versions</em></p>
-->
@@ -98,9 +101,9 @@
<div class="dashboard-panel">
<img alt="" height="250" width="660" style="padding:5px;background:#fff"
-src="http://chart.apis.google.com/chart?&cht=lc&chs=660x250&chxt=x,x,y,r&chxr=0,0,12|1,0,12|2,0,100|3,0,100&chxl=0%3A%7C11/01%7C11/15%7C12/01%7C12/15%7C01/01%7C01/15%7C02/01%7C02/15%7C03/01%7C03/15%7C04/01%7C04/15%7C05/01%7C1%3A%7C2010%7C%7C%7C%7C2011%7C%7C%7C%7C%7C%7C%7C%7C2011%7C2%3A%7C0%25%7C25%25%7C50%25%7C75%25%7C100%25%7C3%3A%7C0%25%7C25%25%7C50%25%7C75%25%7C100%25&chxp=0,0,1,2,3,4,5,6,7,8,9,10,11,12&chxtc=0,5&chd=t:100.0,99.9,99.8,99.7,100.0,99.9,99.9,99.9,100.0,99.8,99.7,99.6,99.6|92.0,92.7,93.4,94.1,95.2,95.6,96.0,96.3,96.7,96.8,97.0,97.1,97.3|77.4,79.6,82.2,84.4,87.2,88.3,89.7,90.5,91.5,92.0,93.5,93.9,94.3|37.1,40.5,44.3,47.7,51.8,54.3,58.3,59.7,61.5,63.0,66.4,68.0,69.8|0.0,0.0,0.0,0.0,0.4,0.6,0.7,0.8,1.1,1.7,2.5,3.1,4.0|0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,1.7,2.2,3.0&chm=b,c3df9b,0,1,0|tAndroid 1.6,689326,1,0,15,,t::-5|b,b4db77,1,2,0|tAndroid 2.1,547a19,2,0,15,,t::-5|b,a5db51,2,3,0|tAndroid 2.2,3f5e0e,3,0,15,,t::-5|b,96dd28,3,4,0|b,83c916,4,5,0|B,6fad0c,5,6,0&chg=7,25&chdl=Android 1.5|Android 1.6|Android 2.1|Android 2.2|Android 2.3|Android 2.3.3&chco=add274,9dd14f,8ece2a,7ab61c,659b11,507d08" />
+src="http://chart.apis.google.com/chart?&cht=lc&chs=660x250&chxt=x,x,y,r&chxr=0,0,12|1,0,12|2,0,100|3,0,100&chxl=0%3A%7C01/01%7C01/15%7C02/01%7C02/15%7C03/01%7C03/15%7C04/01%7C04/15%7C05/01%7C05/15%7C06/01%7C06/15%7C07/01%7C1%3A%7C2011%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C2011%7C2%3A%7C0%25%7C25%25%7C50%25%7C75%25%7C100%25%7C3%3A%7C0%25%7C25%25%7C50%25%7C75%25%7C100%25&chxp=0,0,1,2,3,4,5,6,7,8,9,10,11,12&chxtc=0,5&chd=t:100.0,99.9,99.9,99.9,100.0,99.8,99.7,99.6,99.6,99.5,99.4,99.3,99.2|95.2,95.6,96.0,96.3,96.7,96.8,97.0,97.1,97.3,97.5,97.5,97.5,97.7|87.2,88.3,89.7,90.5,91.5,92.0,93.5,93.9,94.3,94.8,95.0,95.2,95.5|51.8,54.3,58.3,59.7,61.5,63.0,66.4,68.0,69.8,71.5,73.9,75.4,77.6|0.4,0.6,0.7,0.8,1.1,1.7,2.5,3.1,4.0,6.1,9.5,13.6,17.8|0.0,0.0,0.0,0.0,0.0,1.0,1.7,2.2,3.0,5.1,8.4,12.6,16.8&chm=b,c3df9b,0,1,0|b,b4db77,1,2,0|tAndroid 2.1,547a19,2,0,15,,t::-5|b,a5db51,2,3,0|tAndroid2.2,3f5e0e,3,0,15,,t::-5|b,96dd28,3,4,0|b,83c916,4,5,0|tAndroid2.3.3,131d02,5,11,15,,t::-5|B,6fad0c,5,6,0&chg=7,25&chdl=Android 1.5|Android 1.6|Android 2.1|Android2.2|Android 2.3|Android 2.3.3&chco=add274,9dd14f,8ece2a,7ab61c,659b11,507d08" />
-<p><em>Last historical dataset collected during two weeks ending on May 2, 2011</em></p>
+<p><em>Last historical dataset collected during a 14-day period ending on July 5, 2011</em></p>
</div><!-- end dashboard-panel -->
diff --git a/docs/html/resources/dashboard/screens.jd b/docs/html/resources/dashboard/screens.jd
index bdaae0d..e61e799 100644
--- a/docs/html/resources/dashboard/screens.jd
+++ b/docs/html/resources/dashboard/screens.jd
@@ -60,7 +60,7 @@
<div class="dashboard-panel">
<img alt="" width="400" height="250"
-src="http://chart.googleapis.com/chart?cht=p&chs=400x250&chco=c4df9b,6fad0c&chl=xlarge%20/%20mdpi|large%20/%20mdpi|normal%20/%20hdpi|normal%20/%20ldpi|normal%20/%20mdpi|small%20/%20hdpi&chd=t%3A0.5,2.6,75.5,1.2,17.1,3.2" />
+src="http://chart.googleapis.com/chart?cht=p&chs=400x250&chco=c4df9b,6fad0c&chl=Xlarge%20/%20mdpi|Large%20/%20mdpi|Normal%20/%20hdpi|Normal%20/%20ldpi|Normal%20/%20mdpi|Small%20/%20hdpi&chd=t%3A0.9,2.8,75,1.0,17,3.3" />
<table>
<tr>
@@ -71,31 +71,31 @@
<th scope="col">xhdpi</th>
</tr>
<tr><th scope="row">small</th>
-<td></td> <!-- ldpi -->
-<td></td> <!-- mdpi -->
-<td>3.2%</td> <!-- hdpi -->
-<td></td> <!-- xhdpi -->
+<td></td> <!-- small/ldpi -->
+<td></td> <!-- small/mdpi -->
+<td>3.3%</td> <!-- small/hdpi -->
+<td></td> <!-- small/xhdpi -->
</tr>
<tr><th scope="row">normal</th>
-<td>1.2%</td> <!-- ldpi -->
-<td>17.1%</td> <!-- mdpi -->
-<td>75.5%</td> <!-- hdpi -->
-<td></td> <!-- xhdpi -->
+<td>1%</td> <!-- normal/ldpi -->
+<td>17%</td> <!-- normal/mdpi -->
+<td>75%</td> <!-- normal/hdpi -->
+<td></td> <!-- normal/xhdpi -->
</tr>
<tr><th scope="row">large</th>
-<td></td> <!-- ldpi -->
-<td>2.6%</td> <!-- mdpi -->
-<td></td> <!-- hdpi -->
-<td></td> <!-- xhdpi -->
+<td></td> <!-- large/ldpi -->
+<td>2.8%</td> <!-- large/mdpi -->
+<td></td> <!-- large/hdpi -->
+<td></td> <!-- large/xhdpi -->
</tr>
<tr><th scope="row">xlarge</th>
-<td></td> <!-- ldpi -->
-<td>0.5%</td> <!-- mdpi -->
-<td></td> <!-- hdpi -->
-<td></td> <!-- xhdpi -->
+<td></td> <!-- xlarge/ldpi -->
+<td>0.9%</td> <!-- xlarge/mdpi -->
+<td></td> <!-- xlarge/hdpi -->
+<td></td> <!-- xlarge/xhdpi -->
</tr>
</table>
-<p><em>Data collected during a 7-day period ending on May 6, 2011</em></p>
+<p><em>Data collected during a 7-day period ending on July 1, 2011</em></p>
</div>
diff --git a/docs/html/sdk/eclipse-adt.jd b/docs/html/sdk/eclipse-adt.jd
index 935bf63..b4f1b27 100644
--- a/docs/html/sdk/eclipse-adt.jd
+++ b/docs/html/sdk/eclipse-adt.jd
@@ -1,8 +1,8 @@
page.title=ADT Plugin for Eclipse
-adt.zip.version=11.0.0
-adt.zip.download=ADT-11.0.0.zip
-adt.zip.bytes=TODO
-adt.zip.checksum=TODO
+adt.zip.version=12.0.0
+adt.zip.download=ADT-12.0.0.zip
+adt.zip.bytes=5651973
+adt.zip.checksum=8ad85d0f3da4a2b8dadfddcc2d66dbcb
@jd:body
@@ -95,13 +95,64 @@
</style>
-
<div class="toggleable opened">
<a href="#" onclick="return toggleDiv(this)">
<img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-img" height="9px"
width="9px" />
+ADT 12.0.0</a> <em>(June 2011)</em>
+ <div class="toggleme">
+<dl>
+
+<dt>Dependencies:</dt>
+
+<dd>ADT 12.0.0 is designed for use with <a href="{@docRoot}sdk/tools-notes.html">SDK Tools r12</a>. If you haven't
+already installed SDK Tools r12 into your SDK, use
+the Android SDK and AVD Manager to do so.</dd>
+
+<dt>Visual Layout Editor:</dt>
+<dd>
+<ul>
+ <li>New RelativeLayout drop support with guideline suggestions for
+ attachments and cycle prevention
+ (<a href="http://tools.android.com/recent/revampedrelativelayoutsupport">more info</a>).</li>
+ <li>Resize support in most layouts along with
+ guideline snapping to the sizes dictated by <code>wrap_content</code> and <code>match_parent</code>.
+ In LinearLayout, sizes are mapped to weights instead of pixel widths.
+ (<a href="http://tools.android.com/recent/resizesupport">more info</a>).</li>
+ <li>Previews of drawables and colors in the resource chooser dialogs
+ (<a href="http://tools.android.com/recent/imageandcolorpreviews">more info</a>).</li>
+ <li>Improved error messages and links for rendering errors including
+ detection of misspelled class names
+ (<a href="http://tools.android.com/recent/improvedrenderingerrordiagnostics">more info</a>).</li>
+</ul>
+</dd>
+
+<dt>Build system</dt>
+<dd>
+<ul>
+ <li>A new option lets you disable the packaging step in the automatic
+ builders. This improves performance when saving files by not
+ performing a full build, which can take a long time for large projects.
+ If the option is enabled, the APK is packaged when the
+ application is deployed to a device or emulator or when the
+ release APK is exported (<a href="http://tools.android.com/recent/finercontroloveradtbuildprocess">more info</a>).</li>
+</ul>
+</dd>
+
+<dt>Bug fixes</dt>
+<dd>Many bug fixes are part of this release
+(<a href="http://tools.android.com/recent/adt12bugfixroundup">more info</a>).</dd>
+
+</div>
+</div>
+
+
+<div class="toggleable closed">
+ <a href="#" onclick="return toggleDiv(this)">
+ <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-img" height="9px"
+width="9px" />
ADT 11.0.0</a> <em>(June 2011)</em>
- <dd class="toggleme">
+ <div class="toggleme">
<dl>
@@ -229,6 +280,9 @@
</div>
+
+
+
<div class="toggleable closed">
<a href="#" onclick="return toggleDiv(this)">
<img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-img" height="9px"
diff --git a/docs/html/sdk/index.jd b/docs/html/sdk/index.jd
index e7b8fbb..5cf37c1 100644
--- a/docs/html/sdk/index.jd
+++ b/docs/html/sdk/index.jd
@@ -1,21 +1,21 @@
page.title=Android SDK
sdk.redirect=0
-sdk.win_installer=installer_r11-windows.exe
-sdk.win_installer_bytes=32883649
-sdk.win_installer_checksum=3dc8a29ae5afed97b40910ef153caa2b
+sdk.win_installer=installer_r12-windows.exe
+sdk.win_installer_bytes=36531492
+sdk.win_installer_checksum=367f0ed4ecd70aefc290d1f7dcb578ab
-sdk.win_download=android-sdk_r11-windows.zip
-sdk.win_bytes=32837554
-sdk.win_checksum=0a2c52b8f8d97a4871ce8b3eb38e3072
+sdk.win_download=android-sdk_r12-windows.zip
+sdk.win_bytes=36486190
+sdk.win_checksum=8d6c104a34cd2577c5506c55d981aebf
-sdk.mac_download=android-sdk_r11-mac_x86.zip
-sdk.mac_bytes=28844968
-sdk.mac_checksum=85bed5ed25aea51f6a447a674d637d1e
+sdk.mac_download=android-sdk_r12-mac_x86.zip
+sdk.mac_bytes=30231118
+sdk.mac_checksum=341544e4572b4b1afab123ab817086e7
-sdk.linux_download=android-sdk_r11-linux_x86.tgz
-sdk.linux_bytes=26984929
-sdk.linux_checksum=026c67f82627a3a70efb197ca3360d0a
+sdk.linux_download=android-sdk_r12-linux_x86.tgz
+sdk.linux_bytes=30034243
+sdk.linux_checksum=f8485275a8dee3d1929936ed538ee99a
@jd:body
diff --git a/docs/html/sdk/sdk_toc.cs b/docs/html/sdk/sdk_toc.cs
index d02c13d..0607aad 100644
--- a/docs/html/sdk/sdk_toc.cs
+++ b/docs/html/sdk/sdk_toc.cs
@@ -134,7 +134,7 @@
</li>
</ul>
<ul>
- <li><a href="<?cs var:toroot ?>sdk/tools-notes.html">SDK Tools, r11</a> <span
+ <li><a href="<?cs var:toroot ?>sdk/tools-notes.html">SDK Tools, r12</a> <span
class="new">new!</span></li>
<li><a href="<?cs var:toroot ?>sdk/win-usb.html">Google USB Driver, r4</a></li>
<li><a href="<?cs var:toroot ?>sdk/compatibility-library.html">Compatibility Library, r2</a> <span
@@ -153,7 +153,7 @@
<span style="display:none" class="zh-TW"></span>
</h2>
<ul>
- <li><a href="<?cs var:toroot ?>sdk/eclipse-adt.html">ADT 11.0.0
+ <li><a href="<?cs var:toroot ?>sdk/eclipse-adt.html">ADT 12.0.0
<span style="display:none" class="de"></span>
<span style="display:none" class="es"></span>
<span style="display:none" class="fr"></span>
diff --git a/docs/html/sdk/tools-notes.jd b/docs/html/sdk/tools-notes.jd
index 64c8f2a..d4ebf8a 100644
--- a/docs/html/sdk/tools-notes.jd
+++ b/docs/html/sdk/tools-notes.jd
@@ -62,9 +62,36 @@
}
</style>
+
<div class="toggleable opened">
<a href="#" onclick="return toggleDiv(this)">
<img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-img" height="9px" width="9px" />
+SDK Tools, Revision 12</a> <em>(June 2011)</em>
+ <div class="toggleme">
+ <dl>
+<dt>Dependencies:</dt>
+<dd>
+<p>If you are developing in Eclipse with ADT, note that the SDK Tools r12 is designed for use with
+ADT 12.0.0 and later. If you haven't already, we highly recommend updating your <a
+href="{@docRoot}sdk/eclipse-adt.html">ADT Plugin</a> to 12.0.0.</p>
+
+<p>If you are developing outside Eclipse, you must have <a href="http://ant.apache.org/">Apache
+Ant</a> 1.8 or later.</p>
+
+<dt>General notes:</dt>
+<dd>
+ <ul>
+ <li>The AVD manager and emulator can now use system images
+ compiled for ARM v7 and x86 CPUs.</li>
+ </ul>
+</dd>
+</dl>
+</div>
+</div>
+
+<div class="toggleable closed">
+ <a href="#" onclick="return toggleDiv(this)">
+ <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-img" height="9px" width="9px" />
SDK Tools, Revision 11</a> <em>(May 2011)</em>
<div class="toggleme">
<dl>
diff --git a/keystore/java/android/security/KeyChain.java b/keystore/java/android/security/KeyChain.java
index e91bcab..6229331 100644
--- a/keystore/java/android/security/KeyChain.java
+++ b/keystore/java/android/security/KeyChain.java
@@ -81,6 +81,13 @@
* avoid prompting the user with {@link #choosePrivateKeyAlias
* choosePrivateKeyAlias} on subsequent connections. If the alias is
* no longer valid, null will be returned on lookups using that value
+ *
+ * <p>An application can request the installation of private keys and
+ * certificates via the {@code Intent} provided by {@link
+ * #createInstallIntent}. Private keys installed via this {@code
+ * Intent} will be accessible via {@link #choosePrivateKeyAlias} while
+ * Certificate Authority (CA) certificates will be trusted by all
+ * applications through the default {@code X509TrustManager}.
*/
// TODO reference intent for credential installation when public
public final class KeyChain {
@@ -135,8 +142,6 @@
/**
* Optional extra to specify a {@code String} credential name on
* the {@code Intent} returned by {@link #createInstallIntent}.
- *
- * @hide TODO make public
*/
// Compatible with old com.android.certinstaller.CredentialHelper.CERT_NAME_KEY
public static final String EXTRA_NAME = "name";
@@ -150,8 +155,6 @@
*
* <p>{@link #EXTRA_NAME} may be used to provide a default alias
* name for the installed certificate.
- *
- * @hide TODO make public
*/
// Compatible with old android.security.Credentials.CERTIFICATE
public static final String EXTRA_CERTIFICATE = "CERT";
@@ -161,7 +164,7 @@
* {@link #createInstallIntent} to specify a PKCS#12 key store to
* install. The extra value should be a {@code byte[]}. The bytes
* may come from an external source or be generated with {@link
- * KeyStore#store} on a "PKCS12" instance.
+ * java.security.KeyStore#store} on a "PKCS12" instance.
*
* <p>The user will be prompted for the password to load the key store.
*
@@ -171,8 +174,6 @@
*
* <p>{@link #EXTRA_NAME} may be used to provide a default alias
* name for the installed credentials.
- *
- * @hide TODO make public
*/
// Compatible with old android.security.Credentials.PKCS12
public static final String EXTRA_PKCS12 = "PKCS12";
@@ -186,15 +187,13 @@
* <p>Alternatively, {@link #EXTRA_CERTIFICATE} or {@link
* #EXTRA_PKCS12} maybe used to specify the bytes of an X.509
* certificate or a PKCS#12 key store for installation. These
- * extras may be combined with {@link EXTRA_NAME} to provide a
+ * extras may be combined with {@link #EXTRA_NAME} to provide a
* default alias name for credentials being installed.
*
* <p>When used with {@link Activity#startActivityForResult},
* {@link Activity#RESULT_OK} will be returned if a credential was
* successfully installed, otherwise {@link
* Activity#RESULT_CANCELED} will be returned.
- *
- * @hide TODO make public with createInstallIntent, EXTRA_NAME, EXTRA_CERTIFICATE, EXTRA_PKCS12
*/
public static Intent createInstallIntent() {
Intent intent = new Intent(ACTION_INSTALL);
diff --git a/packages/SettingsProvider/AndroidManifest.xml b/packages/SettingsProvider/AndroidManifest.xml
index e5f52e2..dd0d064 100644
--- a/packages/SettingsProvider/AndroidManifest.xml
+++ b/packages/SettingsProvider/AndroidManifest.xml
@@ -6,7 +6,6 @@
android:label="@string/app_label"
android:process="system"
android:backupAgent="SettingsBackupAgent"
- android:fullBackupAgent="SettingsBackupAgent"
android:killAfterRestore="false"
android:icon="@drawable/ic_launcher_settings">
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
index 9469601..3a7a6e1 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
@@ -36,7 +36,7 @@
import android.app.backup.BackupDataInput;
import android.app.backup.BackupDataOutput;
import android.app.backup.BackupAgentHelper;
-import android.app.backup.FullBackup;
+import android.app.backup.FullBackupDataOutput;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
@@ -132,58 +132,22 @@
byte[] wifiSupplicantData = getWifiSupplicant(FILE_WIFI_SUPPLICANT);
byte[] wifiConfigData = getFileData(mWifiConfigFile);
- // This same agent class is used for both full and incremental backups. A full
- // backup is flagged by a 'null' oldState argument. In the case of a full backup,
- // the output is structured as tarfile contents.
- if (oldState != null) {
- long[] stateChecksums = readOldChecksums(oldState);
+ long[] stateChecksums = readOldChecksums(oldState);
- stateChecksums[STATE_SYSTEM] =
- writeIfChanged(stateChecksums[STATE_SYSTEM], KEY_SYSTEM, systemSettingsData, data);
- stateChecksums[STATE_SECURE] =
- writeIfChanged(stateChecksums[STATE_SECURE], KEY_SECURE, secureSettingsData, data);
- stateChecksums[STATE_LOCALE] =
- writeIfChanged(stateChecksums[STATE_LOCALE], KEY_LOCALE, locale, data);
- stateChecksums[STATE_WIFI_SUPPLICANT] =
- writeIfChanged(stateChecksums[STATE_WIFI_SUPPLICANT], KEY_WIFI_SUPPLICANT,
- wifiSupplicantData, data);
- stateChecksums[STATE_WIFI_CONFIG] =
- writeIfChanged(stateChecksums[STATE_WIFI_CONFIG], KEY_WIFI_CONFIG, wifiConfigData,
- data);
+ stateChecksums[STATE_SYSTEM] =
+ writeIfChanged(stateChecksums[STATE_SYSTEM], KEY_SYSTEM, systemSettingsData, data);
+ stateChecksums[STATE_SECURE] =
+ writeIfChanged(stateChecksums[STATE_SECURE], KEY_SECURE, secureSettingsData, data);
+ stateChecksums[STATE_LOCALE] =
+ writeIfChanged(stateChecksums[STATE_LOCALE], KEY_LOCALE, locale, data);
+ stateChecksums[STATE_WIFI_SUPPLICANT] =
+ writeIfChanged(stateChecksums[STATE_WIFI_SUPPLICANT], KEY_WIFI_SUPPLICANT,
+ wifiSupplicantData, data);
+ stateChecksums[STATE_WIFI_CONFIG] =
+ writeIfChanged(stateChecksums[STATE_WIFI_CONFIG], KEY_WIFI_CONFIG, wifiConfigData,
+ data);
- writeNewChecksums(stateChecksums, newState);
- } else {
- // Write the data to the staging file, then emit that as our tarfile
- // representation of the backed-up settings.
- String root = getFilesDir().getAbsolutePath();
- File stage = new File(root, STAGE_FILE);
- try {
- FileOutputStream filestream = new FileOutputStream(stage);
- BufferedOutputStream bufstream = new BufferedOutputStream(filestream);
- DataOutputStream out = new DataOutputStream(bufstream);
-
- out.writeInt(FULL_BACKUP_VERSION);
-
- out.writeInt(systemSettingsData.length);
- out.write(systemSettingsData);
- out.writeInt(secureSettingsData.length);
- out.write(secureSettingsData);
- out.writeInt(locale.length);
- out.write(locale);
- out.writeInt(wifiSupplicantData.length);
- out.write(wifiSupplicantData);
- out.writeInt(wifiConfigData.length);
- out.write(wifiConfigData);
-
- out.flush(); // also flushes downstream
-
- // now we're set to emit the tar stream
- FullBackup.backupToTar(getPackageName(), FullBackup.DATA_TREE_TOKEN, null,
- root, stage.getAbsolutePath(), data);
- } finally {
- stage.delete();
- }
- }
+ writeNewChecksums(stateChecksums, newState);
}
@Override
@@ -221,6 +185,45 @@
}
@Override
+ public void onFullBackup(FullBackupDataOutput data) throws IOException {
+ byte[] systemSettingsData = getSystemSettings();
+ byte[] secureSettingsData = getSecureSettings();
+ byte[] locale = mSettingsHelper.getLocaleData();
+ byte[] wifiSupplicantData = getWifiSupplicant(FILE_WIFI_SUPPLICANT);
+ byte[] wifiConfigData = getFileData(mWifiConfigFile);
+
+ // Write the data to the staging file, then emit that as our tarfile
+ // representation of the backed-up settings.
+ String root = getFilesDir().getAbsolutePath();
+ File stage = new File(root, STAGE_FILE);
+ try {
+ FileOutputStream filestream = new FileOutputStream(stage);
+ BufferedOutputStream bufstream = new BufferedOutputStream(filestream);
+ DataOutputStream out = new DataOutputStream(bufstream);
+
+ out.writeInt(FULL_BACKUP_VERSION);
+
+ out.writeInt(systemSettingsData.length);
+ out.write(systemSettingsData);
+ out.writeInt(secureSettingsData.length);
+ out.write(secureSettingsData);
+ out.writeInt(locale.length);
+ out.write(locale);
+ out.writeInt(wifiSupplicantData.length);
+ out.write(wifiSupplicantData);
+ out.writeInt(wifiConfigData.length);
+ out.write(wifiConfigData);
+
+ out.flush(); // also flushes downstream
+
+ // now we're set to emit the tar stream
+ fullBackupFile(stage, data);
+ } finally {
+ stage.delete();
+ }
+ }
+
+ @Override
public void onRestoreFile(ParcelFileDescriptor data, long size,
int type, String domain, String relpath, long mode, long mtime)
throws IOException {
diff --git a/packages/SharedStorageBackup/AndroidManifest.xml b/packages/SharedStorageBackup/AndroidManifest.xml
index 258059c..39c36f1 100644
--- a/packages/SharedStorageBackup/AndroidManifest.xml
+++ b/packages/SharedStorageBackup/AndroidManifest.xml
@@ -23,7 +23,7 @@
<application android:allowClearUserData="false"
android:permission="android.permission.CONFIRM_FULL_BACKUP"
- android:fullBackupAgent=".SharedStorageAgent"
+ android:backupAgent=".SharedStorageAgent"
android:allowBackup="false" >
</application>
</manifest>
diff --git a/packages/SharedStorageBackup/src/com/android/sharedstoragebackup/SharedStorageAgent.java b/packages/SharedStorageBackup/src/com/android/sharedstoragebackup/SharedStorageAgent.java
index b02ca2e..6c677b8 100644
--- a/packages/SharedStorageBackup/src/com/android/sharedstoragebackup/SharedStorageAgent.java
+++ b/packages/SharedStorageBackup/src/com/android/sharedstoragebackup/SharedStorageAgent.java
@@ -1,9 +1,10 @@
package com.android.sharedstoragebackup;
-import android.app.backup.FullBackup;
import android.app.backup.FullBackupAgent;
+import android.app.backup.FullBackup;
import android.app.backup.BackupDataInput;
import android.app.backup.BackupDataOutput;
+import android.app.backup.FullBackupDataOutput;
import android.content.Context;
import android.os.Environment;
import android.os.ParcelFileDescriptor;
@@ -30,9 +31,11 @@
}
}
+ /**
+ * Full backup of the shared-storage filesystem
+ */
@Override
- public void onBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
- ParcelFileDescriptor newState) throws IOException {
+ public void onFullBackup(FullBackupDataOutput output) throws IOException {
// If there are shared-storage volumes available, run the inherited directory-
// hierarchy backup process on them. By convention in the Storage Manager, the
// "primary" shared storage volume is first in the list.
@@ -43,20 +46,12 @@
// shared/N/path/to/file
// The restore will then extract to the given volume
String domain = FullBackup.SHARED_PREFIX + i;
- processTree(null, domain, v.getPath(), null, data);
+ fullBackupFileTree(null, domain, v.getPath(), null, output);
}
}
}
/**
- * Incremental onRestore() implementation is not used.
- */
- @Override
- public void onRestore(BackupDataInput data, int appVersionCode, ParcelFileDescriptor newState)
- throws IOException {
- }
-
- /**
* Full restore of one file to shared storage
*/
@Override
@@ -88,6 +83,6 @@
Slog.e(TAG, "Skipping data with malformed path " + relpath);
}
- FullBackup.restoreToFile(data, size, type, mode, mtime, outFile, false);
+ FullBackup.restoreFile(data, size, type, -1, mtime, outFile);
}
}
diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java
index 3aa1239..6afccec 100644
--- a/services/java/com/android/server/BackupManagerService.java
+++ b/services/java/com/android/server/BackupManagerService.java
@@ -23,6 +23,7 @@
import android.app.IApplicationThread;
import android.app.IBackupAgent;
import android.app.PendingIntent;
+import android.app.backup.BackupAgent;
import android.app.backup.BackupDataOutput;
import android.app.backup.FullBackup;
import android.app.backup.RestoreSet;
@@ -64,6 +65,7 @@
import android.os.WorkSource;
import android.provider.Settings;
import android.util.EventLog;
+import android.util.Log;
import android.util.Slog;
import android.util.SparseArray;
import android.util.SparseIntArray;
@@ -1587,8 +1589,7 @@
// Initiate the target's backup pass
prepareOperationTimeout(token, TIMEOUT_BACKUP_INTERVAL);
- agent.doBackup(savedState, backupData, newState, false,
- token, mBackupManagerBinder);
+ agent.doBackup(savedState, backupData, newState, token, mBackupManagerBinder);
boolean success = waitUntilOperationComplete(token);
if (!success) {
@@ -1764,30 +1765,31 @@
if (agent != null) {
try {
ApplicationInfo app = pkg.applicationInfo;
- boolean sendApk = mIncludeApks
+ final boolean sendApk = mIncludeApks
&& ((app.flags & ApplicationInfo.FLAG_FORWARD_LOCK) == 0)
&& ((app.flags & ApplicationInfo.FLAG_SYSTEM) == 0 ||
(app.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0);
sendOnBackupPackage(pkg.packageName);
- {
- BackupDataOutput output = new BackupDataOutput(
- mOutputFile.getFileDescriptor());
+ BackupDataOutput output = new BackupDataOutput(
+ mOutputFile.getFileDescriptor());
- if (DEBUG) Slog.d(TAG, "Writing manifest for " + pkg.packageName);
- writeAppManifest(pkg, mManifestFile, sendApk);
- FullBackup.backupToTar(pkg.packageName, null, null,
- mFilesDir.getAbsolutePath(),
- mManifestFile.getAbsolutePath(),
- output);
+ if (DEBUG) Slog.d(TAG, "Writing manifest for " + pkg.packageName);
+ writeAppManifest(pkg, mManifestFile, sendApk);
+ FullBackup.backupToTar(pkg.packageName, null, null,
+ mFilesDir.getAbsolutePath(),
+ mManifestFile.getAbsolutePath(),
+ output);
+
+ if (sendApk) {
+ writeApkToBackup(pkg, output);
}
- if (DEBUG) Slog.d(TAG, "Calling doBackup()");
+ if (DEBUG) Slog.d(TAG, "Calling doFullBackup()");
final int token = generateToken();
prepareOperationTimeout(token, TIMEOUT_FULL_BACKUP_INTERVAL);
- agent.doBackup(null, mOutputFile, null, sendApk,
- token, mBackupManagerBinder);
+ agent.doFullBackup(mOutputFile, token, mBackupManagerBinder);
if (!waitUntilOperationComplete(token)) {
Slog.e(TAG, "Full backup failed on package " + pkg.packageName);
} else {
@@ -1802,6 +1804,29 @@
tearDown(pkg);
}
+ private void writeApkToBackup(PackageInfo pkg, BackupDataOutput output) {
+ // Forward-locked apps, system-bundled .apks, etc are filtered out before we get here
+ final String appSourceDir = pkg.applicationInfo.sourceDir;
+ final String apkDir = new File(appSourceDir).getParent();
+ FullBackup.backupToTar(pkg.packageName, FullBackup.APK_TREE_TOKEN, null,
+ apkDir, appSourceDir, output);
+
+ // Save associated .obb content if it exists and we did save the apk
+ // check for .obb and save those too
+ final File obbDir = Environment.getExternalStorageAppObbDirectory(pkg.packageName);
+ if (obbDir != null) {
+ if (DEBUG) Log.i(TAG, "obb dir: " + obbDir.getAbsolutePath());
+ File[] obbFiles = obbDir.listFiles();
+ if (obbFiles != null) {
+ final String obbDirName = obbDir.getAbsolutePath();
+ for (File obb : obbFiles) {
+ FullBackup.backupToTar(pkg.packageName, FullBackup.OBB_TREE_TOKEN, null,
+ obbDirName, obb.getAbsolutePath(), output);
+ }
+ }
+ }
+ }
+
private void backupSharedStorage() throws RemoteException {
PackageInfo pkg = null;
try {
@@ -1813,7 +1838,7 @@
final int token = generateToken();
prepareOperationTimeout(token, TIMEOUT_SHARED_BACKUP_INTERVAL);
- agent.doBackup(null, mOutputFile, null, false, token, mBackupManagerBinder);
+ agent.doFullBackup(mOutputFile, token, mBackupManagerBinder);
if (!waitUntilOperationComplete(token)) {
Slog.e(TAG, "Full backup failed on shared storage");
} else {
@@ -1933,7 +1958,7 @@
static class FileMetadata {
String packageName; // name of the owning app
String installerPackageName; // name of the market-type app that installed the owner
- int type; // e.g. FullBackup.TYPE_DIRECTORY
+ int type; // e.g. BackupAgent.TYPE_DIRECTORY
String domain; // e.g. FullBackup.DATABASE_TREE_TOKEN
String path; // subpath within the semantic domain
long mode; // e.g. 0666 (actually int)
@@ -2182,15 +2207,15 @@
// If we haven't sent any data to this app yet, we probably
// need to clear it first. Check that.
if (!mClearedPackages.contains(pkg)) {
- // apps with their own full backup agents are
+ // apps with their own backup agents are
// responsible for coherently managing a full
// restore.
- if (mTargetApp.fullBackupAgentName == null) {
+ if (mTargetApp.backupAgentName == null) {
if (DEBUG) Slog.d(TAG, "Clearing app data preparatory to full restore");
clearApplicationDataSynchronous(pkg);
} else {
- if (DEBUG) Slog.d(TAG, "full backup agent ("
- + mTargetApp.fullBackupAgentName + ") => no clear");
+ if (DEBUG) Slog.d(TAG, "backup agent ("
+ + mTargetApp.backupAgentName + ") => no clear");
}
mClearedPackages.add(pkg);
} else {
@@ -2686,7 +2711,7 @@
StringBuilder b = new StringBuilder(128);
// mode string
- b.append((info.type == FullBackup.TYPE_DIRECTORY) ? 'd' : '-');
+ b.append((info.type == BackupAgent.TYPE_DIRECTORY) ? 'd' : '-');
b.append(((info.mode & 0400) != 0) ? 'r' : '-');
b.append(((info.mode & 0200) != 0) ? 'w' : '-');
b.append(((info.mode & 0100) != 0) ? 'x' : '-');
@@ -2746,9 +2771,9 @@
}
switch (typeChar) {
- case '0': info.type = FullBackup.TYPE_FILE; break;
+ case '0': info.type = BackupAgent.TYPE_FILE; break;
case '5': {
- info.type = FullBackup.TYPE_DIRECTORY;
+ info.type = BackupAgent.TYPE_DIRECTORY;
if (info.size != 0) {
Slog.w(TAG, "Directory entry with nonzero size in header");
info.size = 0;
diff --git a/services/java/com/android/server/NetworkManagementService.java b/services/java/com/android/server/NetworkManagementService.java
index 1c150f8..da1bf83 100644
--- a/services/java/com/android/server/NetworkManagementService.java
+++ b/services/java/com/android/server/NetworkManagementService.java
@@ -54,6 +54,7 @@
import java.io.InputStreamReader;
import java.net.Inet4Address;
import java.net.InetAddress;
+import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
@@ -1230,4 +1231,65 @@
return -1;
}
}
+
+ public void setDefaultInterfaceForDns(String iface) throws IllegalStateException {
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService");
+ try {
+ String cmd = "resolver setdefaultif " + iface;
+
+ mConnector.doCommand(cmd);
+ } catch (NativeDaemonConnectorException e) {
+ throw new IllegalStateException(
+ "Error communicating with native daemon to set default interface", e);
+ }
+ }
+
+ public void setDnsServersForInterface(String iface, String[] servers)
+ throws IllegalStateException {
+ mContext.enforceCallingOrSelfPermission(android.Manifest.permission.CHANGE_NETWORK_STATE,
+ "NetworkManagementService");
+ try {
+ String cmd = "resolver setifdns " + iface;
+ for (String s : servers) {
+ if (s != null && !"0.0.0.0".equals(s) &&
+ !"::".equals(s) && !"0:0:0:0:0:0:0:0".equals(s)) {
+ cmd += " " + InetAddress.getByName(s).getHostAddress();
+ }
+ }
+
+ mConnector.doCommand(cmd);
+ } catch (UnknownHostException e) {
+ throw new IllegalStateException("failed to resolve dns address.", e);
+ } catch (NativeDaemonConnectorException e) {
+ throw new IllegalStateException(
+ "Error communicating with native deamon to set dns for interface", e);
+ }
+ }
+
+ public void flushDefaultDnsCache() throws IllegalStateException {
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService");
+ try {
+ String cmd = "resolver flushdefaultif";
+
+ mConnector.doCommand(cmd);
+ } catch (NativeDaemonConnectorException e) {
+ throw new IllegalStateException(
+ "Error communicating with native deamon to flush default interface", e);
+ }
+ }
+
+ public void flushInterfaceDnsCache(String iface) throws IllegalStateException {
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService");
+ try {
+ String cmd = "resolver flushif " + iface;
+
+ mConnector.doCommand(cmd);
+ } catch (NativeDaemonConnectorException e) {
+ throw new IllegalStateException(
+ "Error communicating with native deamon to flush interface " + iface, e);
+ }
+ }
}
diff --git a/services/java/com/android/server/SystemBackupAgent.java b/services/java/com/android/server/SystemBackupAgent.java
index 08c6699..950f3b6 100644
--- a/services/java/com/android/server/SystemBackupAgent.java
+++ b/services/java/com/android/server/SystemBackupAgent.java
@@ -138,7 +138,7 @@
if (outFile == null) {
Slog.w(TAG, "Skipping unrecognized system file: [ " + domain + " : " + path + " ]");
}
- FullBackup.restoreToFile(data, size, type, mode, mtime, outFile, true);
+ FullBackup.restoreFile(data, size, type, mode, mtime, outFile);
if (restoredWallpaper) {
WallpaperManagerService wallpaper =
diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java
index 7725891..5f0922e 100644
--- a/services/java/com/android/server/WifiService.java
+++ b/services/java/com/android/server/WifiService.java
@@ -36,6 +36,7 @@
import android.net.wifi.WifiStateMachine;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiConfiguration.KeyMgmt;
+import android.net.wifi.WifiWatchdogService;
import android.net.wifi.WpsConfiguration;
import android.net.wifi.WpsResult;
import android.net.ConnectivityManager;
diff --git a/services/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
index 10dd924..80cdf6b 100644
--- a/services/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -436,7 +436,8 @@
public IAccessibilityServiceConnection registerEventListener(IEventListener listener) {
mSecurityPolicy.enforceCallingPermission(Manifest.permission.RETRIEVE_WINDOW_CONTENT,
FUNCTION_REGISTER_EVENT_LISTENER);
- ComponentName componentName = new ComponentName("foo.bar", "FakeAccessibilityService");
+ ComponentName componentName = new ComponentName("foo.bar",
+ "AutomationAccessibilityService");
synchronized (mLock) {
Service oldService = mComponentNameToServiceMap.get(componentName);
if (oldService != null) {
@@ -829,7 +830,7 @@
boolean mCanRetrieveScreenContent;
- boolean mIsFake;
+ boolean mIsAutomation;
final Callback mCallback = new Callback();
@@ -842,12 +843,12 @@
new SparseArray<AccessibilityEvent>();
public Service(ComponentName componentName,
- AccessibilityServiceInfo accessibilityServiceInfo, boolean isFake) {
+ AccessibilityServiceInfo accessibilityServiceInfo, boolean isAutomation) {
mId = sIdCounter++;
mComponentName = componentName;
mAccessibilityServiceInfo = accessibilityServiceInfo;
- mIsFake = isFake;
- if (!isFake) {
+ mIsAutomation = isAutomation;
+ if (!isAutomation) {
mCanRetrieveScreenContent = accessibilityServiceInfo.getCanRetrieveWindowContent();
mIntent = new Intent().setComponent(mComponentName);
mIntent.putExtra(Intent.EXTRA_CLIENT_LABEL,
@@ -881,7 +882,7 @@
* @return True if binding is successful.
*/
public boolean bind() {
- if (!mIsFake && mService == null) {
+ if (!mIsAutomation && mService == null) {
return mContext.bindService(mIntent, this, Context.BIND_AUTO_CREATE);
}
return false;
@@ -898,7 +899,7 @@
synchronized (mLock) {
tryRemoveServiceLocked(this);
}
- if (!mIsFake) {
+ if (!mIsAutomation) {
mContext.unbindService(this);
}
mService = null;
@@ -938,16 +939,19 @@
IAccessibilityInteractionConnection connection = null;
synchronized (mLock) {
final boolean permissionGranted = mSecurityPolicy.canRetrieveWindowContent(this);
- if (permissionGranted) {
+ if (!permissionGranted) {
+ return null;
+ } else {
connection = getConnectionToRetrievalAllowingWindowLocked();
+ if (connection == null) {
+ if (DEBUG) {
+ Slog.e(LOG_TAG, "No interaction connection to a retrieve "
+ + "allowing window.");
+ }
+ return null;
+ }
}
}
- if (connection == null) {
- if (DEBUG) {
- Slog.e(LOG_TAG, "No interaction connection to a retrieve allowing window.");
- }
- return null;
- }
final long identityToken = Binder.clearCallingIdentity();
try {
final int interactionId = mInteractionIdCounter.getAndIncrement();
@@ -982,16 +986,18 @@
synchronized (mLock) {
final boolean permissionGranted =
mSecurityPolicy.canGetAccessibilityNodeInfoLocked(this, accessibilityWindowId);
- if (permissionGranted) {
+ if (!permissionGranted) {
+ return null;
+ } else {
connection = getConnectionToRetrievalAllowingWindowLocked();
+ if (connection == null) {
+ if (DEBUG) {
+ Slog.e(LOG_TAG, "No interaction connection to focused window.");
+ }
+ return null;
+ }
}
}
- if (connection == null) {
- if (DEBUG) {
- Slog.e(LOG_TAG, "No interaction connection to focused window.");
- }
- return null;
- }
final long identityToken = Binder.clearCallingIdentity();
try {
final int interactionId = mInteractionIdCounter.getAndIncrement();
@@ -1025,17 +1031,19 @@
synchronized (mLock) {
final boolean permissionGranted =
mSecurityPolicy.canGetAccessibilityNodeInfoLocked(this, accessibilityWindowId);
- if (permissionGranted) {
+ if (!permissionGranted) {
+ return null;
+ } else {
connection = mWindowIdToInteractionConnectionMap.get(accessibilityWindowId);
+ if (connection == null) {
+ if (DEBUG) {
+ Slog.e(LOG_TAG, "No interaction connection to window: "
+ + accessibilityWindowId);
+ }
+ return null;
+ }
}
}
- if (connection == null) {
- if (DEBUG) {
- Slog.e(LOG_TAG, "No interaction connection to window: "
- + accessibilityWindowId);
- }
- return null;
- }
final long identityToken = Binder.clearCallingIdentity();
try {
final int interactionId = mInteractionIdCounter.getAndIncrement();
@@ -1066,17 +1074,19 @@
synchronized (mLock) {
final boolean permissionGranted = mSecurityPolicy.canPerformActionLocked(this,
accessibilityWindowId, action);
- if (permissionGranted) {
+ if (!permissionGranted) {
+ return false;
+ } else {
connection = mWindowIdToInteractionConnectionMap.get(accessibilityWindowId);
+ if (connection == null) {
+ if (DEBUG) {
+ Slog.e(LOG_TAG, "No interaction connection to window: "
+ + accessibilityWindowId);
+ }
+ return false;
+ }
}
}
- if (connection == null) {
- if (DEBUG) {
- Slog.e(LOG_TAG, "No interaction connection to window: "
- + accessibilityWindowId);
- }
- return false;
- }
final long identityToken = Binder.clearCallingIdentity();
try {
final int interactionId = mInteractionIdCounter.getAndIncrement();
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 48b0b66..29cccb6 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -1953,6 +1953,9 @@
if ("1".equals(SystemProperties.get("debug.checkjni"))) {
debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
}
+ if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
+ debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
+ }
if ("1".equals(SystemProperties.get("debug.assert"))) {
debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
}
diff --git a/services/java/com/android/server/usb/UsbDeviceManager.java b/services/java/com/android/server/usb/UsbDeviceManager.java
index c157cf1..d645160 100644
--- a/services/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/java/com/android/server/usb/UsbDeviceManager.java
@@ -72,7 +72,9 @@
private static final String STATE_PATH =
"/sys/class/android_usb/android0/state";
private static final String MASS_STORAGE_FILE_PATH =
- "/sys/class/android_usb/f_mass_storage/lun/file";
+ "/sys/class/android_usb/android0/f_mass_storage/lun/file";
+ private static final String RNDIS_ETH_ADDR_PATH =
+ "/sys/class/android_usb/android0/f_rndis/ethaddr";
private static final int MSG_UPDATE_STATE = 0;
private static final int MSG_ENABLE_ADB = 1;
@@ -132,6 +134,7 @@
mSettingsManager = settingsManager;
PackageManager pm = mContext.getPackageManager();
mHasUsbAccessory = pm.hasSystemFeature(PackageManager.FEATURE_USB_ACCESSORY);
+ initRndisAddress();
// create a thread for our Handler
HandlerThread thread = new HandlerThread("UsbDeviceManager",
@@ -166,6 +169,29 @@
mHandler.sendEmptyMessage(MSG_SYSTEM_READY);
}
+ private static void initRndisAddress() {
+ // configure RNDIS ethernet address based on our serial number using the same algorithm
+ // we had been previously using in kernel board files
+ final int ETH_ALEN = 6;
+ int address[] = new int[ETH_ALEN];
+ // first byte is 0x02 to signify a locally administered address
+ address[0] = 0x02;
+
+ String serial = SystemProperties.get("ro.serialno", "1234567890ABCDEF");
+ int serialLength = serial.length();
+ // XOR the USB serial across the remaining 5 bytes
+ for (int i = 0; i < serialLength; i++) {
+ address[i % (ETH_ALEN - 1) + 1] ^= (int)serial.charAt(i);
+ }
+ String addrString = String.format("%02X:%02X:%02X:%02X:%02X:%02X",
+ address[0], address[1], address[2], address[3], address[4], address[5]);
+ try {
+ FileUtils.stringToFile(RNDIS_ETH_ADDR_PATH, addrString);
+ } catch (IOException e) {
+ Slog.e(TAG, "failed to write to " + RNDIS_ETH_ADDR_PATH);
+ }
+ }
+
private static String addFunction(String functions, String function) {
if (!containsFunction(functions, function)) {
if (functions.length() > 0) {
diff --git a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
index bac15a6..8a60b5a 100755
--- a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
@@ -1030,13 +1030,8 @@
case EVENT_NV_READY:{
Log.d(LOG_TAG, "Event EVENT_NV_READY Received");
//Inform the Service State Tracker
- mEriManager.loadEriFile();
mNvLoadedRegistrants.notifyRegistrants();
- if(mEriManager.isEriFileLoaded()) {
- // when the ERI file is loaded
- Log.d(LOG_TAG, "ERI read, notify registrants");
- mEriFileLoadedRegistrants.notifyRegistrants();
- }
+ prepareEri();
}
break;
@@ -1424,6 +1419,19 @@
return false;
}
+ public void prepareEri() {
+ mEriManager.loadEriFile();
+ if(mEriManager.isEriFileLoaded()) {
+ // when the ERI file is loaded
+ log("ERI read, notify registrants");
+ mEriFileLoadedRegistrants.notifyRegistrants();
+ }
+ }
+
+ public boolean isEriFileLoaded() {
+ return mEriManager.isEriFileLoaded();
+ }
+
protected void log(String s) {
if (DBG)
Log.d(LOG_TAG, "[CDMAPhone] " + s);
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java
index 318cf37..459cf87 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java
@@ -21,13 +21,15 @@
import com.android.internal.telephony.EventLogTags;
import com.android.internal.telephony.RILConstants;
+import android.content.Intent;
import android.telephony.SignalStrength;
import android.telephony.ServiceState;
import android.telephony.cdma.CdmaCellLocation;
import android.os.AsyncResult;
import android.os.Message;
+import android.provider.Telephony.Intents;
-
+import android.text.TextUtils;
import android.util.Log;
import android.util.EventLog;
@@ -37,6 +39,7 @@
CDMALTEPhone mCdmaLtePhone;
private ServiceState mLteSS; // The last LTE state from Voice Registration
+ private String mCurrentSpn = null;
public CdmaLteServiceStateTracker(CDMALTEPhone phone) {
super(phone);
@@ -73,6 +76,9 @@
pollState();
// Signal strength polling stops when radio is off.
queueNextSignalStrengthPoll();
+
+ // load ERI file
+ phone.prepareEri();
break;
case EVENT_SIM_RECORDS_LOADED:
CdmaLteUiccRecords sim = (CdmaLteUiccRecords)phone.mIccRecords;
@@ -84,6 +90,10 @@
mIsMinInfoReady = true;
updateOtaspState();
}
+ // SID/NID/PRL is loaded. Poll service state
+ // again to update to the roaming state with
+ // the latest variables.
+ pollState();
break;
default:
super.handleMessage(msg);
@@ -319,7 +329,7 @@
}
if (hasChanged) {
- if (cm.getNvState().isNVReady()) {
+ if (phone.isEriFileLoaded()) {
String eriText;
// Now the CDMAPhone sees the new ServiceState so it can get the
// new ERI text
@@ -334,13 +344,6 @@
}
ss.setOperatorAlphaLong(eriText);
}
- if (cm.getSimState().isSIMReady()) {
- // SIM is found on the device. Read the operator name from the card.
- ss.setOperatorAlphaLong(phone.mIccRecords.getServiceProviderName());
-
- // If SIM card is present, Eri will not be used. Turn it off
- ss.setCdmaEriIconIndex(EriInfo.ROAMING_INDICATOR_OFF);
- }
String operatorNumeric;
@@ -465,6 +468,43 @@
}
@Override
+ protected void updateSpnDisplay() {
+ // mOperatorAlphaLong contains the ERI text
+ String plmn = ss.getOperatorAlphaLong();
+
+ boolean showSpn = false;
+ String spn = null;
+ if (cm.getSimState().isSIMReady()) {
+ // SIM is found on the device. Read the operator name from the card.
+ showSpn = ((CdmaLteUiccRecords)phone.mIccRecords).getCsimSpnDisplayCondition();
+ spn = phone.mIccRecords.getServiceProviderName();
+
+ // double check we are not printing identicall test
+ if (TextUtils.equals(plmn, spn)) showSpn = false;
+ }
+
+ if (!TextUtils.equals(plmn, mCurPlmn) ||
+ !TextUtils.equals(spn, mCurrentSpn)) {
+ boolean showPlmn = plmn != null;
+ if (DBG) {
+ log(String.format("updateSpnDisplay: changed sending intent" +
+ " showPlmn='%b' plmn='%s' showSpn='%b' spn='%s'",
+ showPlmn, plmn, showSpn, spn));
+ }
+ Intent intent = new Intent(Intents.SPN_STRINGS_UPDATED_ACTION);
+ intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
+ intent.putExtra(Intents.EXTRA_SHOW_SPN, showSpn);
+ intent.putExtra(Intents.EXTRA_SPN, spn);
+ intent.putExtra(Intents.EXTRA_SHOW_PLMN, showPlmn);
+ intent.putExtra(Intents.EXTRA_PLMN, plmn);
+ phone.getContext().sendStickyBroadcast(intent);
+ }
+
+ mCurPlmn = plmn;
+ mCurrentSpn = spn;
+ }
+
+ @Override
protected void log(String s) {
Log.d(LOG_TAG, "[CdmaLteSST] " + s);
}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccRecords.java b/telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccRecords.java
index 73b5d97..10515f7 100755
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccRecords.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccRecords.java
@@ -38,7 +38,7 @@
// From CSIM application
private byte[] mEFpl = null;
private byte[] mEFli = null;
- boolean csimSpnDisplayCondition = false;
+ boolean mCsimSpnDisplayCondition = false;
private String mMdn;
private String mMin;
private String mPrlVersion;
@@ -235,7 +235,7 @@
IccUtils.bytesToHexString(data));
// C.S0065 for EF_SPN decoding
- csimSpnDisplayCondition = ((0x02 & data[0]) > 0)?true:false;
+ mCsimSpnDisplayCondition = ((0x01 & data[0]) != 0) ? true : false;
int encoding = data[1];
int language = data[2];
@@ -272,7 +272,7 @@
log("spn decode error: " + e);
}
if (DBG) log("spn=" + spn);
- if (DBG) log("spnCondition=" + csimSpnDisplayCondition);
+ if (DBG) log("spnCondition=" + mCsimSpnDisplayCondition);
phone.setSystemProperty(PROPERTY_ICC_OPERATOR_ALPHA, spn);
}
@@ -437,6 +437,10 @@
return mPrlVersion;
}
+ public boolean getCsimSpnDisplayCondition() {
+ return mCsimSpnDisplayCondition;
+ }
+
@Override
public boolean isProvisioned() {
// If UICC card has CSIM app, look for MDN and MIN field
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
index 5ebdd22..24a468a 100755
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
@@ -127,7 +127,7 @@
private static final String WAKELOCK_TAG = "ServiceStateTracker";
/** Contains the name of the registered network in CDMA (either ONS or ERI text). */
- private String curPlmn = null;
+ protected String mCurPlmn = null;
protected String mMdn;
private int mHomeSystemId[] = null;
@@ -484,7 +484,7 @@
// mOperatorAlphaLong contains the ERI text
String plmn = ss.getOperatorAlphaLong();
- if (!TextUtils.equals(plmn, curPlmn)) {
+ if (!TextUtils.equals(plmn, mCurPlmn)) {
// Allow A blank plmn, "" to set showPlmn to true. Previously, we
// would set showPlmn to true only if plmn was not empty, i.e. was not
// null and not blank. But this would cause us to incorrectly display
@@ -503,7 +503,7 @@
phone.getContext().sendStickyBroadcast(intent);
}
- curPlmn = plmn;
+ mCurPlmn = plmn;
}
@Override
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
index a6b131a..fe57d0d 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
@@ -608,16 +608,18 @@
if (dcac.dataConnection != null) {
dcac.dataConnection.resetRetryCount();
}
-
- Collection<ApnContext> apnList = dcac.getApnListSync();
- for (ApnContext apnContext : apnList) {
- apnContext.setState(State.IDLE);
- }
}
}
// Only check for default APN state
for (ApnContext apnContext : mApnContexts.values()) {
+ if (apnContext.getState() == State.FAILED) {
+ // By this time, alarms for all failed Apns
+ // should be stopped if any.
+ // Make sure to set the state back to IDLE
+ // so that setup data can happen.
+ apnContext.setState(State.IDLE);
+ }
if (apnContext.isReady()) {
if (apnContext.getState() == State.IDLE) {
apnContext.setReason(reason);
diff --git a/services/java/com/android/server/WifiWatchdogService.java b/wifi/java/android/net/wifi/WifiWatchdogService.java
similarity index 98%
rename from services/java/com/android/server/WifiWatchdogService.java
rename to wifi/java/android/net/wifi/WifiWatchdogService.java
index 1356e2a..bce4b3a 100644
--- a/services/java/com/android/server/WifiWatchdogService.java
+++ b/wifi/java/android/net/wifi/WifiWatchdogService.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.server;
+package android.net.wifi;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
@@ -23,12 +23,9 @@
import android.content.IntentFilter;
import android.database.ContentObserver;
import android.net.ConnectivityManager;
+import android.net.DnsPinger;
import android.net.NetworkInfo;
import android.net.Uri;
-import android.net.wifi.ScanResult;
-import android.net.wifi.SupplicantState;
-import android.net.wifi.WifiInfo;
-import android.net.wifi.WifiManager;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
@@ -159,7 +156,7 @@
BLACKLISTED_AP
}
- WifiWatchdogService(Context context) {
+ public WifiWatchdogService(Context context) {
mContext = context;
mContentResolver = context.getContentResolver();
mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);