diff options
113 files changed, 1931 insertions, 652 deletions
diff --git a/api/current.txt b/api/current.txt index d009a64f355c..9ad7b4ed2257 100644 --- a/api/current.txt +++ b/api/current.txt @@ -183,14 +183,14 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android.app.backup { 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 @@ package android.app.backup { 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 @@ package android.security { 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 21bb62eeeced..42c35afe2d87 100644 --- a/cmds/dumpstate/dumpstate.c +++ b/cmds/dumpstate/dumpstate.c @@ -47,9 +47,11 @@ static void dumpstate() { 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 @@ static void dumpstate() { #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 @@ int main(int argc, char *argv[]) { 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 1ec7a964e5cd..eee14fb1a5b3 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -2013,15 +2013,10 @@ public final class ActivityThread { 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 8af78fadfc44..087f83c396dd 100644 --- a/core/java/android/app/IBackupAgent.aidl +++ b/core/java/android/app/IBackupAgent.aidl @@ -51,7 +51,6 @@ oneway interface IBackupAgent { void doBackup(in ParcelFileDescriptor oldState, in ParcelFileDescriptor data, in ParcelFileDescriptor newState, - boolean storeApk, int token, IBackupManager callbackBinder); /** @@ -81,6 +80,25 @@ oneway interface IBackupAgent { 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 63f325870f91..dce0a972d332 100644 --- a/core/java/android/app/backup/BackupAgent.java +++ b/core/java/android/app/backup/BackupAgent.java @@ -20,13 +20,22 @@ import android.app.IBackupAgent; 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 @@ public abstract class BackupAgent extends ContextWrapper { 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 @@ public abstract class BackupAgent extends ContextWrapper { throws IOException; /** + * The default implementation backs up the entirety of the application's "owned" + * file system trees to the output. + */ + 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); + } + + /** + * 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. + */ + 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, - int type, String domain, String path, long mode, long mtime) + File destination, int type, long mode, long mtime) throws IOException { - // empty stub implementation + FullBackup.restoreFile(data, size, type, mode, mtime, destination); } /** - * Package-private, used only for dispatching an extra step during full backup + * Only specialized platform agents should overload this entry point to support + * restores to crazy non-app locations. + * @hide */ - void onSaveApk(BackupDataOutput data) { + 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 abstract class BackupAgent extends ContextWrapper { 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 @@ public abstract class BackupAgent extends ContextWrapper { 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 @@ public abstract class BackupAgent extends ContextWrapper { } @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 3b70e19ad244..d7f1c9f0fab4 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 @@ import libcore.io.Libcore; /** * 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 class FullBackup { 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 @@ public class FullBackup { } // 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 df1c3639bc58..faea76aee148 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 000000000000..99dab1f76018 --- /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 454cb3195316..ddb6ef0d2f53 100644 --- a/core/java/android/content/pm/ApplicationInfo.java +++ b/core/java/android/content/pm/ApplicationInfo.java @@ -91,15 +91,6 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { 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 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { dest.writeInt(installLocation); dest.writeString(manageSpaceActivityName); dest.writeString(backupAgentName); - dest.writeString(fullBackupAgentName); dest.writeInt(descriptionRes); } @@ -593,7 +583,6 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { 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 208869b6c2fd..53d6bb17a551 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -1517,17 +1517,6 @@ public class PackageParser { } } - // 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 index 4e33938b2ca8..f2d84ebc9889 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 fcf479631b03..f23052604528 100644 --- a/core/java/android/os/INetworkManagementService.aidl +++ b/core/java/android/os/INetworkManagementService.aidl @@ -241,4 +241,23 @@ interface INetworkManagementService */ 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 05e39ac55a89..673b187a9d36 100644 --- a/core/java/android/os/Process.java +++ b/core/java/android/os/Process.java @@ -522,6 +522,9 @@ public class Process { 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 39c6f576b5d7..382fcf34757c 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 7ea0fbd84e64..d0712d5b662d 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 88f59d4bdd21..72263a72c109 100644 --- a/core/java/android/view/MotionEvent.java +++ b/core/java/android/view/MotionEvent.java @@ -2881,6 +2881,10 @@ public final class MotionEvent extends InputEvent implements Parcelable { 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 f7d55f6f00af..0294e3f81600 100644 --- a/core/java/android/webkit/CallbackProxy.java +++ b/core/java/android/webkit/CallbackProxy.java @@ -119,6 +119,7 @@ class CallbackProxy extends Handler { 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 @@ class CallbackProxy extends Handler { 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 @@ class CallbackProxy extends Handler { } break; } + case SEARCHBOX_IS_SUPPORTED_CALLBACK: { + SearchBoxImpl searchBox = (SearchBoxImpl) mWebView.getSearchBox(); + Boolean supported = (Boolean) msg.obj; + searchBox.handleIsSupportedCallback(supported); + break; + } } } @@ -1627,4 +1635,10 @@ class CallbackProxy extends Handler { 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 57c7b035efad..5075302fb936 100644 --- a/core/java/android/webkit/SearchBox.java +++ b/core/java/android/webkit/SearchBox.java @@ -83,10 +83,19 @@ public interface SearchBox { 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 480f5d7a5b44..61fb2ce9f160 100644 --- a/core/java/android/webkit/SearchBoxImpl.java +++ b/core/java/android/webkit/SearchBoxImpl.java @@ -92,9 +92,19 @@ final class SearchBoxImpl implements SearchBox { = "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 @@ final class SearchBoxImpl implements SearchBox { } } + @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 7ba86a58a13a..ffa52d10060c 100644 --- a/core/java/android/webkit/WebView.java +++ b/core/java/android/webkit/WebView.java @@ -3467,6 +3467,40 @@ public class WebView extends AbsoluteLayout 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 @@ public class WebView extends AbsoluteLayout } // 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 @@ public class WebView extends AbsoluteLayout // 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 @@ public class WebView extends AbsoluteLayout 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 @@ public class WebView extends AbsoluteLayout 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 @@ public class WebView extends AbsoluteLayout } 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 @@ public class WebView extends AbsoluteLayout 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 @@ public class WebView extends AbsoluteLayout 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 @@ public class WebView extends AbsoluteLayout 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 @@ public class WebView extends AbsoluteLayout 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 4f97066aa381..3357220ec28e 100644 --- a/core/java/android/webkit/WebViewCore.java +++ b/core/java/android/webkit/WebViewCore.java @@ -577,8 +577,10 @@ public final class WebViewCore { 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 @@ public final class WebViewCore { 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 @@ public final class WebViewCore { 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 7d43e94ff695..252fc8fae5f4 100644 --- a/core/java/android/webkit/ZoomManager.java +++ b/core/java/android/webkit/ZoomManager.java @@ -1111,6 +1111,12 @@ class ZoomManager { 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 fc8bce8d868d..427fd3ef42c3 100644 --- a/core/java/android/widget/LinearLayout.java +++ b/core/java/android/widget/LinearLayout.java @@ -301,49 +301,55 @@ public class LinearLayout extends ViewGroup { 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 c91f1a61306d..772e8e9e67d4 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -8901,7 +8901,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener 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 b872e22c3587..7cb002c08b6a 100644 --- a/core/java/com/android/internal/os/ZygoteConnection.java +++ b/core/java/com/android/internal/os/ZygoteConnection.java @@ -328,8 +328,8 @@ class ZygoteConnection { 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 @@ class ZygoteConnection { 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 479788d39d0a..3b497e46f3c5 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 @@ public class ActionMenuItemView extends LinearLayout 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 @@ public class ActionMenuItemView extends LinearLayout // 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 @@ public class ActionMenuItemView extends LinearLayout // 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 2fec9cd09f5b..b86eb132163b 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 @@ package com.android.internal.view.menu; 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 @@ public class ActionMenuPresenter extends BaseMenuPresenter { 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 @@ public class ActionMenuPresenter extends BaseMenuPresenter { 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 @@ public class ActionMenuPresenter extends BaseMenuPresenter { @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 @@ public class ActionMenuPresenter extends BaseMenuPresenter { 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 @@ public class ActionMenuPresenter extends BaseMenuPresenter { 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; + } + if (mStrictWidthLimit) { + cellsRemaining -= ActionMenuView.measureChildForCells(v, + cellSize, cellsRemaining, querySpec, 0); + } else { + v.measure(querySpec, querySpec); } - v.measure(querySpec, querySpec); final int measuredWidth = v.getMeasuredWidth(); widthLimit -= measuredWidth; if (firstActionWidth == 0) { @@ -341,18 +368,25 @@ public class ActionMenuPresenter extends BaseMenuPresenter { // 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; + } + if (mStrictWidthLimit) { + final int cells = ActionMenuView.measureChildForCells(v, + cellSize, cellsRemaining, querySpec, 0); + cellsRemaining -= cells; + if (cells == 0) { + isAction = false; } + } else { + v.measure(querySpec, querySpec); } - v.measure(querySpec, querySpec); final int measuredWidth = v.getMeasuredWidth(); widthLimit -= measuredWidth; if (firstActionWidth == 0) { @@ -360,10 +394,10 @@ public class ActionMenuPresenter extends BaseMenuPresenter { } 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 class ActionMenuPresenter extends BaseMenuPresenter { } 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 7b4f2164e78e..cfe9e5990e02 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 @@ import android.widget.LinearLayout; 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 class ActionMenuView extends LinearLayout implements MenuBuilder.ItemInvo 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 @@ public class ActionMenuView extends LinearLayout implements MenuBuilder.ItemInvo @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 @@ public class ActionMenuView extends LinearLayout implements MenuBuilder.ItemInvo 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 @@ public class ActionMenuView extends LinearLayout implements MenuBuilder.ItemInvo } 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 @@ public class ActionMenuView extends LinearLayout implements MenuBuilder.ItemInvo } } - // 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 @@ public class ActionMenuView extends LinearLayout implements MenuBuilder.ItemInvo 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 @@ public class ActionMenuView extends LinearLayout implements MenuBuilder.ItemInvo } @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 @@ public class ActionMenuView extends LinearLayout implements MenuBuilder.ItemInvo @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 class ActionMenuView extends LinearLayout implements MenuBuilder.ItemInvo 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 7b1dfb07c55f..20b7d8094478 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 @@ public final class MenuItemImpl implements MenuItem { return mMenuInfo; } + public void actionFormatChanged() { + mMenu.onItemActionRequestChanged(this); + } + /** * @return Whether the menu should show icons for menu items. */ @@ -534,9 +538,7 @@ public final class MenuItemImpl implements MenuItem { } 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 953328c03ddd..9fef2a910fc1 100644 --- a/core/java/com/android/internal/widget/ActionBarContainer.java +++ b/core/java/com/android/internal/widget/ActionBarContainer.java @@ -19,6 +19,8 @@ package com.android.internal.widget; 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 @@ public class ActionBarContainer extends FrameLayout { 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 class ActionBarContainer extends FrameLayout { 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 @@ public class ActionBarContainer extends FrameLayout { } @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 @@ public class ActionBarContainer extends FrameLayout { @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 @@ public class ActionBarContainer extends FrameLayout { 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 306d2236693a..28710734da83 100644 --- a/core/java/com/android/server/NetworkManagementSocketTagger.java +++ b/core/java/com/android/server/NetworkManagementSocketTagger.java @@ -30,6 +30,7 @@ import java.nio.charset.Charsets; 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 @@ public final class NetworkManagementSocketTagger extends SocketTagger { * */ 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 1a320608efae..49eaf1912617 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 Binary files differnew file mode 100644 index 000000000000..3ea6c445b946 --- /dev/null +++ b/core/res/res/drawable-hdpi/ab_bottom_solid_dark_holo.9.png 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 Binary files differnew file mode 100644 index 000000000000..6c6fcd2a45eb --- /dev/null +++ b/core/res/res/drawable-hdpi/ab_bottom_solid_inverse_holo.9.png 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 Binary files differnew file mode 100644 index 000000000000..854631ec22de --- /dev/null +++ b/core/res/res/drawable-hdpi/ab_bottom_solid_light_holo.9.png 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 Binary files differnew file mode 100644 index 000000000000..aef6142df029 --- /dev/null +++ b/core/res/res/drawable-hdpi/ab_bottom_transparent_dark_holo.9.png 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 Binary files differnew file mode 100644 index 000000000000..d8b5edc3a1e9 --- /dev/null +++ b/core/res/res/drawable-hdpi/ab_bottom_transparent_light_holo.9.png 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 Binary files differnew file mode 100644 index 000000000000..660a234c65f7 --- /dev/null +++ b/core/res/res/drawable-hdpi/ab_solid_dark_holo.9.png 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 Binary files differnew file mode 100644 index 000000000000..9756cf5ceebd --- /dev/null +++ b/core/res/res/drawable-hdpi/ab_solid_light_holo.9.png 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 Binary files differnew file mode 100644 index 000000000000..80213d513886 --- /dev/null +++ b/core/res/res/drawable-hdpi/ab_solid_shadow_holo.9.png 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 Binary files differnew file mode 100644 index 000000000000..6de2bf2c3176 --- /dev/null +++ b/core/res/res/drawable-hdpi/ab_stacked_solid_dark_holo.9.png 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 Binary files differnew file mode 100644 index 000000000000..c23e47320e00 --- /dev/null +++ b/core/res/res/drawable-hdpi/ab_stacked_solid_inverse_holo.9.png 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 Binary files differnew file mode 100644 index 000000000000..343d7c6bd3b8 --- /dev/null +++ b/core/res/res/drawable-hdpi/ab_stacked_solid_light_holo.9.png 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 Binary files differnew file mode 100644 index 000000000000..3de11745ec61 --- /dev/null +++ b/core/res/res/drawable-hdpi/ab_stacked_transparent_dark_holo.9.png 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 Binary files differnew file mode 100644 index 000000000000..da8b0427fe2a --- /dev/null +++ b/core/res/res/drawable-hdpi/ab_stacked_transparent_light_holo.9.png 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 Binary files differnew file mode 100644 index 000000000000..1957c32468ad --- /dev/null +++ b/core/res/res/drawable-hdpi/ab_transparent_dark_holo.9.png 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 Binary files differnew file mode 100644 index 000000000000..0f1ce73a33d7 --- /dev/null +++ b/core/res/res/drawable-hdpi/ab_transparent_light_holo.9.png 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 Binary files differnew file mode 100644 index 000000000000..3807a48e8f58 --- /dev/null +++ b/core/res/res/drawable-mdpi/ab_bottom_solid_dark_holo.9.png 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 Binary files differnew file mode 100644 index 000000000000..99944386e33c --- /dev/null +++ b/core/res/res/drawable-mdpi/ab_bottom_solid_inverse_holo.9.png 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 Binary files differnew file mode 100644 index 000000000000..564840360fe8 --- /dev/null +++ b/core/res/res/drawable-mdpi/ab_bottom_solid_light_holo.9.png 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 Binary files differnew file mode 100644 index 000000000000..261365d49b4a --- /dev/null +++ b/core/res/res/drawable-mdpi/ab_bottom_transparent_dark_holo.9.png 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 Binary files differnew file mode 100644 index 000000000000..95df5fcc4391 --- /dev/null +++ b/core/res/res/drawable-mdpi/ab_bottom_transparent_light_holo.9.png 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 Binary files differnew file mode 100644 index 000000000000..4a6c3bc9027d --- /dev/null +++ b/core/res/res/drawable-mdpi/ab_solid_dark_holo.9.png 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 Binary files differnew file mode 100644 index 000000000000..93a0c3e19301 --- /dev/null +++ b/core/res/res/drawable-mdpi/ab_solid_light_holo.9.png 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 Binary files differnew file mode 100644 index 000000000000..f3abd078fbc7 --- /dev/null +++ b/core/res/res/drawable-mdpi/ab_solid_shadow_holo.9.png 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 Binary files differnew file mode 100644 index 000000000000..e1d8f67ed004 --- /dev/null +++ b/core/res/res/drawable-mdpi/ab_stacked_solid_dark_holo.9.png 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 Binary files differnew file mode 100644 index 000000000000..9d7e953e4ca0 --- /dev/null +++ b/core/res/res/drawable-mdpi/ab_stacked_solid_inverse_holo.9.png 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 Binary files differnew file mode 100644 index 000000000000..711e0fdae66b --- /dev/null +++ b/core/res/res/drawable-mdpi/ab_stacked_solid_light_holo.9.png 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 Binary files differnew file mode 100644 index 000000000000..9649a2deeb94 --- /dev/null +++ b/core/res/res/drawable-mdpi/ab_stacked_transparent_dark_holo.9.png 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 Binary files differnew file mode 100644 index 000000000000..376e4efc7d00 --- /dev/null +++ b/core/res/res/drawable-mdpi/ab_stacked_transparent_light_holo.9.png 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 Binary files differnew file mode 100644 index 000000000000..99c8fd3d1751 --- /dev/null +++ b/core/res/res/drawable-mdpi/ab_transparent_dark_holo.9.png 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 Binary files differnew file mode 100644 index 000000000000..a86ec34538c0 --- /dev/null +++ b/core/res/res/drawable-mdpi/ab_transparent_light_holo.9.png 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 Binary files differnew file mode 100644 index 000000000000..462e0e0ca8c9 --- /dev/null +++ b/core/res/res/drawable-xhdpi/ab_bottom_solid_dark_holo.9.png 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 Binary files differnew file mode 100644 index 000000000000..939ff4eba165 --- /dev/null +++ b/core/res/res/drawable-xhdpi/ab_bottom_solid_inverse_holo.9.png 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 Binary files differnew file mode 100644 index 000000000000..8f890406f6d6 --- /dev/null +++ b/core/res/res/drawable-xhdpi/ab_bottom_solid_light_holo.9.png 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 Binary files differnew file mode 100644 index 000000000000..ccd53a343944 --- /dev/null +++ b/core/res/res/drawable-xhdpi/ab_bottom_transparent_dark_holo.9.png 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 Binary files differnew file mode 100644 index 000000000000..0b1ae2dc7fa1 --- /dev/null +++ b/core/res/res/drawable-xhdpi/ab_bottom_transparent_light_holo.9.png 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 Binary files differnew file mode 100644 index 000000000000..c8e5efc404a4 --- /dev/null +++ b/core/res/res/drawable-xhdpi/ab_solid_dark_holo.9.png 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 Binary files differnew file mode 100644 index 000000000000..6cb8a0eb03cd --- /dev/null +++ b/core/res/res/drawable-xhdpi/ab_solid_light_holo.9.png 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 Binary files differnew file mode 100644 index 000000000000..49b2669c6815 --- /dev/null +++ b/core/res/res/drawable-xhdpi/ab_solid_shadow_holo.9.png 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 Binary files differnew file mode 100644 index 000000000000..201e21d5f84a --- /dev/null +++ b/core/res/res/drawable-xhdpi/ab_stacked_solid_dark_holo.9.png 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 Binary files differnew file mode 100644 index 000000000000..ac96200639c6 --- /dev/null +++ b/core/res/res/drawable-xhdpi/ab_stacked_solid_inverse_holo.9.png 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 Binary files differnew file mode 100644 index 000000000000..d605d964bede --- /dev/null +++ b/core/res/res/drawable-xhdpi/ab_stacked_solid_light_holo.9.png 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 Binary files differnew file mode 100644 index 000000000000..8ece2a9b0e02 --- /dev/null +++ b/core/res/res/drawable-xhdpi/ab_stacked_transparent_dark_holo.9.png 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 Binary files differnew file mode 100644 index 000000000000..ae0b6b77719c --- /dev/null +++ b/core/res/res/drawable-xhdpi/ab_stacked_transparent_light_holo.9.png 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 Binary files differnew file mode 100644 index 000000000000..d3a38096c1f2 --- /dev/null +++ b/core/res/res/drawable-xhdpi/ab_transparent_dark_holo.9.png 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 Binary files differnew file mode 100644 index 000000000000..7e6e24d2461b --- /dev/null +++ b/core/res/res/drawable-xhdpi/ab_transparent_light_holo.9.png diff --git a/core/res/res/layout/action_menu_item_layout.xml b/core/res/res/layout/action_menu_item_layout.xml index a8f0c22f9626..dca6c52d21ef 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 8206e792dbe5..57a2939b34ed 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 000000000000..269a9b4c4c86 --- /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 aa8c510bc2b6..b92ce6a80f48 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 03b332ee75b6..dd16bd072df6 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 9647bb707c53..e51fc6630277 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 87b9be49f832..9f05cbcba55c 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 54e484ee95de..75acb37b4ded 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="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" /> - <public type="attr" name="textDirection"/> - - <public type="attr" name="actionProviderClass" /> - </resources> diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml index 5244b74fa492..9ee4b6ade4a1 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.Holo.Small"> + <item name="android:textSize">@android:dimen/action_bar_subtitle_text_size</item> </style> - <style name="TextAppearance.Holo.Widget.ActionMode.Subtitle" parent="TextAppearance.Widget.ActionMode.Subtitle"> + <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 78e9975ff70e..23111e6501d4 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 0cbba53b3795..95d89fa1f2c5 100644 --- a/docs/html/guide/publishing/publishing.jd +++ b/docs/html/guide/publishing/publishing.jd @@ -23,6 +23,7 @@ page.title=Publishing on Android Market <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 @@ publisher name:</p> +<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 dac8ce5e98e6..3fcfa89141c2 100644 --- a/docs/html/resources/dashboard/opengl.jd +++ b/docs/html/resources/dashboard/opengl.jd @@ -57,7 +57,7 @@ ending on the data collection date noted below.</p> <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 @@ src="http://chart.googleapis.com/chart?cht=p&chs=400x250&chco=c4df9b,6fad0c&chl= </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 368164d55904..d9adb36eb3be 100644 --- a/docs/html/resources/dashboard/platform-versions.jd +++ b/docs/html/resources/dashboard/platform-versions.jd @@ -51,8 +51,8 @@ Android Market within a 14-day period ending on the data collection date noted b <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 @@ src="http://chart.apis.google.com/chart?&cht=p&chs=460x250&chd=t:2.3,3.0,24.5,65 <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 @@ Android Market within a 14-day period ending on the date indicated on the x-axis <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 bdaae0dcbcb8..e61e79972170 100644 --- a/docs/html/resources/dashboard/screens.jd +++ b/docs/html/resources/dashboard/screens.jd @@ -60,7 +60,7 @@ ending on the data collection date noted below.</p> <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 @@ src="http://chart.googleapis.com/chart?cht=p&chs=400x250&chco=c4df9b,6fad0c&chl= <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 935bf63e0890..b4f1b27aa324 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 @@ padding: .25em 1em; </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 @@ href="http://tools.android.com/recent">Android Tools Project Site</a>.</p> </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 e7b8fbb20c64..5cf37c120233 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 d02c13d1bc2b..0607aad54633 100644 --- a/docs/html/sdk/sdk_toc.cs +++ b/docs/html/sdk/sdk_toc.cs @@ -134,7 +134,7 @@ class="new">new!</span></li> </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 @@ class="new">new!</span></li> <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 64c8f2a33b12..d4ebf8a64a9f 100644 --- a/docs/html/sdk/tools-notes.jd +++ b/docs/html/sdk/tools-notes.jd @@ -62,9 +62,36 @@ padding: .25em 1em; } </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 e91bcab55401..62293315a864 100644 --- a/keystore/java/android/security/KeyChain.java +++ b/keystore/java/android/security/KeyChain.java @@ -81,6 +81,13 @@ import org.apache.harmony.xnet.provider.jsse.TrustedCertificateStore; * 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 @@ public final class KeyChain { /** * 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 @@ public final class KeyChain { * * <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 @@ public final class KeyChain { * {@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 @@ public final class KeyChain { * * <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 @@ public final class KeyChain { * <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 e5f52e24e807..dd0d064ceeef 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 946960122565..3a7a6e153803 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 java.util.zip.CRC32; 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 @@ public class SettingsBackupAgent extends BackupAgentHelper { 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); - - 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(); - } - } + 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); + + writeNewChecksums(stateChecksums, newState); } @Override @@ -221,6 +185,45 @@ public class SettingsBackupAgent extends BackupAgentHelper { } @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 258059c54fce..39c36f1b2ec6 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 b02ca2e761ec..6c677b878501 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 @@ public class SharedStorageAgent extends FullBackupAgent { } } + /** + * 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 @@ public class SharedStorageAgent extends FullBackupAgent { // 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 @@ public class SharedStorageAgent extends FullBackupAgent { 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 3aa1239c8df9..6afccec4df04 100644 --- a/services/java/com/android/server/BackupManagerService.java +++ b/services/java/com/android/server/BackupManagerService.java @@ -23,6 +23,7 @@ import android.app.IActivityManager; 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.SystemClock; 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 @@ class BackupManagerService extends IBackupManager.Stub { // 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 @@ class BackupManagerService extends IBackupManager.Stub { 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 @@ class BackupManagerService extends IBackupManager.Stub { 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 @@ class BackupManagerService extends IBackupManager.Stub { 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 @@ class BackupManagerService extends IBackupManager.Stub { 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 @@ class BackupManagerService extends IBackupManager.Stub { // 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 @@ class BackupManagerService extends IBackupManager.Stub { 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 @@ class BackupManagerService extends IBackupManager.Stub { } 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 1c150f8a65ea..da1bf8303df9 100644 --- a/services/java/com/android/server/NetworkManagementService.java +++ b/services/java/com/android/server/NetworkManagementService.java @@ -54,6 +54,7 @@ import java.io.IOException; 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 @@ class NetworkManagementService extends INetworkManagementService.Stub { 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 08c66996128e..950f3b68f6d5 100644 --- a/services/java/com/android/server/SystemBackupAgent.java +++ b/services/java/com/android/server/SystemBackupAgent.java @@ -138,7 +138,7 @@ public class SystemBackupAgent extends BackupAgentHelper { 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 77258910438b..5f0922ec4f09 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.WifiManager; 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 10dd9244bb1e..80cdf6b2bdda 100644 --- a/services/java/com/android/server/accessibility/AccessibilityManagerService.java +++ b/services/java/com/android/server/accessibility/AccessibilityManagerService.java @@ -436,7 +436,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub 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 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub boolean mCanRetrieveScreenContent; - boolean mIsFake; + boolean mIsAutomation; final Callback mCallback = new Callback(); @@ -842,12 +843,12 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub 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 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub * @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 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub synchronized (mLock) { tryRemoveServiceLocked(this); } - if (!mIsFake) { + if (!mIsAutomation) { mContext.unbindService(this); } mService = null; @@ -938,16 +939,19 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub 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 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub 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 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub 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 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub 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 48b0b667c2f8..29cccb6b6135 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -1953,6 +1953,9 @@ public final class ActivityManagerService extends ActivityManagerNative 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 c157cf16cf47..d64516021c8a 100644 --- a/services/java/com/android/server/usb/UsbDeviceManager.java +++ b/services/java/com/android/server/usb/UsbDeviceManager.java @@ -72,7 +72,9 @@ public class UsbDeviceManager { 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 @@ public class UsbDeviceManager { 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 @@ public class UsbDeviceManager { 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 bac15a6901d3..8a60b5a070f9 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 @@ public class CDMAPhone extends PhoneBase { 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 @@ public class CDMAPhone extends PhoneBase { 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 318cf3728f54..459cf87d5720 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.MccTable; 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 @@ public class CdmaLteServiceStateTracker extends CdmaServiceStateTracker { 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 @@ public class CdmaLteServiceStateTracker extends CdmaServiceStateTracker { 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 @@ public class CdmaLteServiceStateTracker extends CdmaServiceStateTracker { 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 @@ public class CdmaLteServiceStateTracker extends CdmaServiceStateTracker { } 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 @@ public class CdmaLteServiceStateTracker extends CdmaServiceStateTracker { } 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 @@ public class CdmaLteServiceStateTracker extends CdmaServiceStateTracker { } @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 73b5d97c8b97..10515f71cfc5 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 @@ public final class CdmaLteUiccRecords extends SIMRecords { // 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 @@ public final class CdmaLteUiccRecords extends SIMRecords { 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 @@ public final class CdmaLteUiccRecords extends SIMRecords { 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 @@ public final class CdmaLteUiccRecords extends SIMRecords { 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 5ebdd22e3c7e..24a468a7d2c1 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 @@ public class CdmaServiceStateTracker extends ServiceStateTracker { 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 @@ public class CdmaServiceStateTracker extends ServiceStateTracker { // 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 @@ public class CdmaServiceStateTracker extends ServiceStateTracker { 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 a6b131a91106..fe57d0dc1595 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 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { 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 index 1356e2a9b23f..bce4b3ad5f37 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.Intent; 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 @@ public class WifiWatchdogService { BLACKLISTED_AP } - WifiWatchdogService(Context context) { + public WifiWatchdogService(Context context) { mContext = context; mContentResolver = context.getContentResolver(); mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); |