summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Android.mk4
-rw-r--r--api/current.txt117
-rw-r--r--core/java/android/app/ActivityThread.java11
-rw-r--r--core/java/android/app/IBackupAgent.aidl20
-rw-r--r--core/java/android/app/backup/BackupAgent.java288
-rw-r--r--core/java/android/app/backup/FullBackup.java49
-rw-r--r--core/java/android/app/backup/FullBackupAgent.java192
-rw-r--r--core/java/android/app/backup/FullBackupDataOutput.java21
-rw-r--r--core/java/android/content/pm/ApplicationInfo.java11
-rw-r--r--core/java/android/content/pm/PackageParser.java11
-rw-r--r--core/java/android/net/DnsPinger.java (renamed from services/java/com/android/server/DnsPinger.java)2
-rw-r--r--core/java/android/net/IConnectivityManager.aidl5
-rw-r--r--core/java/android/net/http/SslCertificate.java175
-rw-r--r--core/java/android/os/Process.java3
-rw-r--r--core/java/android/provider/MediaStore.java14
-rw-r--r--core/java/android/provider/VoicemailContract.java28
-rw-r--r--core/java/android/speech/tts/AudioPlaybackHandler.java11
-rw-r--r--core/java/android/view/inputmethod/InputMethodSubtype.java6
-rw-r--r--core/java/android/webkit/BrowserFrame.java32
-rw-r--r--core/java/android/webkit/CallbackProxy.java16
-rw-r--r--core/java/android/webkit/SearchBox.java9
-rw-r--r--core/java/android/webkit/SearchBoxImpl.java29
-rw-r--r--core/java/android/webkit/WebView.java36
-rw-r--r--core/java/android/webkit/WebViewFragment.java25
-rw-r--r--core/java/android/webkit/ZoomManager.java6
-rw-r--r--core/java/android/widget/LinearLayout.java42
-rw-r--r--core/java/android/widget/TextView.java2
-rw-r--r--core/java/com/android/internal/net/LegacyVpnInfo.aidl19
-rw-r--r--core/java/com/android/internal/net/LegacyVpnInfo.java69
-rw-r--r--core/java/com/android/internal/net/VpnConfig.java7
-rw-r--r--core/java/com/android/internal/os/ZygoteConnection.java6
-rw-r--r--core/java/com/android/internal/view/menu/ActionMenuItemView.java30
-rw-r--r--core/java/com/android/internal/view/menu/ActionMenuPresenter.java82
-rw-r--r--core/java/com/android/internal/view/menu/ActionMenuView.java228
-rw-r--r--core/java/com/android/internal/view/menu/MenuItemImpl.java8
-rw-r--r--core/java/com/android/internal/widget/ActionBarContainer.java67
-rw-r--r--core/res/AndroidManifest.xml1
-rw-r--r--core/res/res/drawable-hdpi/ab_bottom_solid_dark_holo.9.pngbin0 -> 258 bytes
-rw-r--r--core/res/res/drawable-hdpi/ab_bottom_solid_inverse_holo.9.pngbin0 -> 269 bytes
-rw-r--r--core/res/res/drawable-hdpi/ab_bottom_solid_light_holo.9.pngbin0 -> 289 bytes
-rw-r--r--core/res/res/drawable-hdpi/ab_bottom_transparent_dark_holo.9.pngbin0 -> 225 bytes
-rw-r--r--core/res/res/drawable-hdpi/ab_bottom_transparent_light_holo.9.pngbin0 -> 222 bytes
-rw-r--r--core/res/res/drawable-hdpi/ab_solid_dark_holo.9.pngbin0 -> 248 bytes
-rw-r--r--core/res/res/drawable-hdpi/ab_solid_light_holo.9.pngbin0 -> 248 bytes
-rw-r--r--core/res/res/drawable-hdpi/ab_solid_shadow_holo.9.pngbin0 -> 193 bytes
-rw-r--r--core/res/res/drawable-hdpi/ab_stacked_solid_dark_holo.9.pngbin0 -> 243 bytes
-rw-r--r--core/res/res/drawable-hdpi/ab_stacked_solid_inverse_holo.9.pngbin0 -> 243 bytes
-rw-r--r--core/res/res/drawable-hdpi/ab_stacked_solid_light_holo.9.pngbin0 -> 244 bytes
-rw-r--r--core/res/res/drawable-hdpi/ab_stacked_transparent_dark_holo.9.pngbin0 -> 237 bytes
-rw-r--r--core/res/res/drawable-hdpi/ab_stacked_transparent_light_holo.9.pngbin0 -> 239 bytes
-rw-r--r--core/res/res/drawable-hdpi/ab_transparent_dark_holo.9.pngbin0 -> 247 bytes
-rw-r--r--core/res/res/drawable-hdpi/ab_transparent_light_holo.9.pngbin0 -> 222 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_ab_back_holo_dark.pngbin938 -> 602 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_ab_back_holo_light.pngbin975 -> 546 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_menu_copy.pngbin0 -> 961 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_menu_copy_holo_dark.pngbin479 -> 731 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_menu_copy_holo_light.pngbin578 -> 683 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_menu_cut.pngbin0 -> 1896 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_menu_cut_holo_dark.pngbin1006 -> 1298 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_menu_cut_holo_light.pngbin1493 -> 1130 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_menu_find_holo_dark.pngbin2015 -> 1339 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_menu_find_holo_light.pngbin2015 -> 1190 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_menu_moreoverflow.pngbin0 -> 982 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_menu_moreoverflow_normal_holo_dark.pngbin547 -> 344 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_menu_moreoverflow_normal_holo_light.pngbin588 -> 338 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_menu_paste.pngbin0 -> 1317 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_menu_paste_holo_dark.pngbin709 -> 1018 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_menu_paste_holo_light.pngbin945 -> 893 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_menu_share_holo_dark.pngbin1823 -> 1146 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_menu_share_holo_light.pngbin1823 -> 999 bytes
-rw-r--r--core/res/res/drawable-mdpi/ab_bottom_solid_dark_holo.9.pngbin0 -> 234 bytes
-rw-r--r--core/res/res/drawable-mdpi/ab_bottom_solid_inverse_holo.9.pngbin0 -> 240 bytes
-rw-r--r--core/res/res/drawable-mdpi/ab_bottom_solid_light_holo.9.pngbin0 -> 249 bytes
-rw-r--r--core/res/res/drawable-mdpi/ab_bottom_transparent_dark_holo.9.pngbin0 -> 192 bytes
-rw-r--r--core/res/res/drawable-mdpi/ab_bottom_transparent_light_holo.9.pngbin0 -> 190 bytes
-rw-r--r--core/res/res/drawable-mdpi/ab_solid_dark_holo.9.pngbin0 -> 211 bytes
-rw-r--r--core/res/res/drawable-mdpi/ab_solid_light_holo.9.pngbin0 -> 219 bytes
-rw-r--r--core/res/res/drawable-mdpi/ab_solid_shadow_holo.9.pngbin0 -> 173 bytes
-rw-r--r--core/res/res/drawable-mdpi/ab_stacked_solid_dark_holo.9.pngbin0 -> 219 bytes
-rw-r--r--core/res/res/drawable-mdpi/ab_stacked_solid_inverse_holo.9.pngbin0 -> 219 bytes
-rw-r--r--core/res/res/drawable-mdpi/ab_stacked_solid_light_holo.9.pngbin0 -> 219 bytes
-rw-r--r--core/res/res/drawable-mdpi/ab_stacked_transparent_dark_holo.9.pngbin0 -> 212 bytes
-rw-r--r--core/res/res/drawable-mdpi/ab_stacked_transparent_light_holo.9.pngbin0 -> 211 bytes
-rw-r--r--core/res/res/drawable-mdpi/ab_transparent_dark_holo.9.pngbin0 -> 213 bytes
-rw-r--r--core/res/res/drawable-mdpi/ab_transparent_light_holo.9.pngbin0 -> 200 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_ab_back_holo_dark.pngbin709 -> 466 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_ab_back_holo_light.pngbin728 -> 438 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_menu_copy.pngbin0 -> 758 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_menu_copy_holo_dark.pngbin472 -> 612 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_menu_copy_holo_light.pngbin542 -> 570 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_menu_cut.pngbin0 -> 1182 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_menu_cut_holo_dark.pngbin727 -> 879 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_menu_cut_holo_light.pngbin1006 -> 761 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_menu_find_holo_dark.pngbin1331 -> 923 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_menu_find_holo_light.pngbin1331 -> 863 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_menu_moreoverflow.pngbin0 -> 854 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_menu_moreoverflow_focused_holo_dark.pngbin545 -> 852 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_menu_moreoverflow_focused_holo_light.pngbin552 -> 908 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_menu_moreoverflow_normal_holo_dark.pngbin660 -> 321 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_menu_moreoverflow_normal_holo_light.pngbin697 -> 320 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_menu_paste.pngbin0 -> 936 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_menu_paste_holo_dark.pngbin586 -> 740 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_menu_paste_holo_light.pngbin726 -> 669 bytes
-rw-r--r--[-rwxr-xr-x]core/res/res/drawable-mdpi/ic_menu_share_holo_dark.pngbin1154 -> 874 bytes
-rw-r--r--[-rwxr-xr-x]core/res/res/drawable-mdpi/ic_menu_share_holo_light.pngbin1154 -> 763 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ab_bottom_solid_dark_holo.9.pngbin0 -> 311 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ab_bottom_solid_inverse_holo.9.pngbin0 -> 326 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ab_bottom_solid_light_holo.9.pngbin0 -> 333 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ab_bottom_transparent_dark_holo.9.pngbin0 -> 261 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ab_bottom_transparent_light_holo.9.pngbin0 -> 259 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ab_solid_dark_holo.9.pngbin0 -> 285 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ab_solid_light_holo.9.pngbin0 -> 292 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ab_solid_shadow_holo.9.pngbin0 -> 214 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ab_stacked_solid_dark_holo.9.pngbin0 -> 292 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ab_stacked_solid_inverse_holo.9.pngbin0 -> 292 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ab_stacked_solid_light_holo.9.pngbin0 -> 292 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ab_stacked_transparent_dark_holo.9.pngbin0 -> 285 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ab_stacked_transparent_light_holo.9.pngbin0 -> 284 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ab_transparent_dark_holo.9.pngbin0 -> 285 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ab_transparent_light_holo.9.pngbin0 -> 272 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_ab_back_holo_dark.pngbin0 -> 741 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_ab_back_holo_light.pngbin0 -> 661 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_account_list.pngbin0 -> 2266 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_add.pngbin0 -> 3061 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_agenda.pngbin0 -> 1702 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_allfriends.pngbin0 -> 2574 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_always_landscape_portrait.pngbin0 -> 2866 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_archive.pngbin0 -> 1398 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_attachment.pngbin0 -> 2673 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_back.pngbin0 -> 1319 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_block.pngbin0 -> 2721 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_blocked_user.pngbin0 -> 2473 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_btn_add.pngbin0 -> 3061 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_call.pngbin0 -> 2240 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_camera.pngbin0 -> 1855 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_cc.pngbin0 -> 2203 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_chat_dashboard.pngbin0 -> 1623 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_clear_playlist.pngbin0 -> 2314 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_close_clear_cancel.pngbin0 -> 1709 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_compass.pngbin0 -> 2980 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_compose.pngbin0 -> 1732 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_copy.pngbin0 -> 1095 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_copy_holo_dark.pngbin0 -> 826 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_copy_holo_light.pngbin0 -> 747 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_crop.pngbin0 -> 1602 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_cut.pngbin0 -> 2708 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_cut_holo_dark.pngbin0 -> 1803 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_cut_holo_light.pngbin0 -> 1561 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_day.pngbin0 -> 1685 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_delete.pngbin0 -> 1880 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_directions.pngbin0 -> 1497 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_edit.pngbin0 -> 2656 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_emoticons.pngbin0 -> 2786 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_end_conversation.pngbin0 -> 2483 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_find.pngbin0 -> 2730 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_find_holo_dark.pngbin0 -> 1796 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_find_holo_light.pngbin0 -> 1571 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_forward.pngbin0 -> 1227 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_friendslist.pngbin0 -> 1944 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_gallery.pngbin0 -> 1336 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_goto.pngbin0 -> 1744 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_help.pngbin0 -> 1840 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_help_holo_light.pngbin0 -> 1257 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_home.pngbin0 -> 2239 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_info_details.pngbin0 -> 2763 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_invite.pngbin0 -> 1998 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_login.pngbin0 -> 2178 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_manage.pngbin0 -> 2505 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_mapmode.pngbin0 -> 2583 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_mark.pngbin0 -> 1821 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_month.pngbin0 -> 2423 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_more.pngbin0 -> 2838 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_moreoverflow.pngbin0 -> 1204 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_moreoverflow_focused_holo_dark.pngbin0 -> 1297 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_moreoverflow_focused_holo_light.pngbin0 -> 1377 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_moreoverflow_normal_holo_dark.pngbin0 -> 386 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_moreoverflow_normal_holo_light.pngbin0 -> 370 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_my_calendar.pngbin0 -> 1933 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_mylocation.pngbin0 -> 2923 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_myplaces.pngbin0 -> 2109 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_notifications.pngbin0 -> 2245 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_paste.pngbin0 -> 1828 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_paste_holo_dark.pngbin0 -> 1288 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_paste_holo_light.pngbin0 -> 1085 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_play_clip.pngbin0 -> 1479 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_preferences.pngbin0 -> 2507 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_recent_history.pngbin0 -> 3001 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_refresh.pngbin0 -> 2857 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_report_image.pngbin0 -> 1972 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_revert.pngbin0 -> 2077 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_rotate.pngbin0 -> 3113 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_save.pngbin0 -> 1546 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_search.pngbin0 -> 2469 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_search_holo_dark.pngbin0 -> 2976 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_search_holo_light.pngbin0 -> 1629 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_selectall_holo_dark.pngbin0 -> 1264 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_selectall_holo_light.pngbin0 -> 1712 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_send.pngbin0 -> 1775 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_set_as.pngbin0 -> 1805 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_settings_holo_light.pngbin0 -> 1622 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_share.pngbin0 -> 2422 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_share_holo_dark.pngbin0 -> 1566 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_share_holo_light.pngbin0 -> 1352 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_slideshow.pngbin0 -> 1462 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_sort_alphabetically.pngbin0 -> 2133 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_sort_by_size.pngbin0 -> 902 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_star.pngbin0 -> 2354 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_start_conversation.pngbin0 -> 2130 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_stop.pngbin0 -> 1287 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_today.pngbin0 -> 1897 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_upload.pngbin0 -> 1309 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_upload_you_tube.pngbin0 -> 1306 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_view.pngbin0 -> 2378 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_week.pngbin0 -> 1938 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_menu_zoom.pngbin0 -> 2670 bytes
-rw-r--r--core/res/res/layout-land/ssl_certificate.xml107
-rw-r--r--core/res/res/layout/action_menu_item_layout.xml6
-rw-r--r--core/res/res/layout/ssl_certificate.xml429
-rw-r--r--core/res/res/values-w480dp/bools.xml1
-rw-r--r--core/res/res/values-w480dp/config.xml21
-rwxr-xr-xcore/res/res/values/attrs.xml4
-rw-r--r--core/res/res/values/attrs_manifest.xml8
-rw-r--r--core/res/res/values/bools.xml1
-rwxr-xr-xcore/res/res/values/config.xml10
-rw-r--r--core/res/res/values/public.xml38
-rwxr-xr-xcore/res/res/values/strings.xml8
-rw-r--r--core/res/res/values/styles.xml92
-rw-r--r--core/res/res/values/themes.xml67
-rw-r--r--docs/html/guide/topics/graphics/index.jd25
-rw-r--r--docs/html/guide/topics/graphics/opengl.jd232
-rw-r--r--docs/html/guide/topics/usb/adk.jd5
-rw-r--r--docs/html/resources/resources-data.js10
-rw-r--r--include/media/mediametadataretriever.h1
-rw-r--r--include/media/stagefright/MediaExtractor.h9
-rw-r--r--include/surfaceflinger/IGraphicBufferAlloc.h2
-rw-r--r--include/utils/threads.h8
-rw-r--r--keystore/java/android/security/KeyChain.java19
-rw-r--r--libs/gui/IGraphicBufferAlloc.cpp13
-rw-r--r--libs/gui/SurfaceTexture.cpp6
-rw-r--r--libs/gui/tests/Surface_test.cpp22
-rw-r--r--libs/utils/Threads.cpp23
-rw-r--r--media/java/android/media/MediaFile.java2
-rw-r--r--media/java/android/media/MediaMetadataRetriever.java5
-rw-r--r--media/java/android/media/MediaScanner.java5
-rw-r--r--media/java/android/media/RingtoneManager.java21
-rw-r--r--media/libstagefright/MPEG4Extractor.cpp4
-rw-r--r--media/libstagefright/MediaExtractor.cpp9
-rw-r--r--media/libstagefright/StagefrightMediaScanner.cpp1
-rw-r--r--media/libstagefright/StagefrightMetadataRetriever.cpp5
-rw-r--r--media/libstagefright/include/MPEG4Extractor.h1
-rw-r--r--packages/SettingsProvider/AndroidManifest.xml1
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java109
-rw-r--r--packages/SharedStorageBackup/AndroidManifest.xml2
-rw-r--r--packages/SharedStorageBackup/src/com/android/sharedstoragebackup/SharedStorageAgent.java21
-rw-r--r--packages/SystemUI/AndroidManifest.xml4
-rw-r--r--packages/SystemUI/res/layout/usb_preference_buttons.xml43
-rw-r--r--packages/SystemUI/res/values/strings.xml9
-rw-r--r--packages/SystemUI/src/com/android/systemui/usb/UsbPreferenceActivity.java96
-rw-r--r--services/java/com/android/server/BackupManagerService.java73
-rw-r--r--services/java/com/android/server/ConnectivityService.java32
-rw-r--r--services/java/com/android/server/InputMethodManagerService.java7
-rw-r--r--services/java/com/android/server/SystemBackupAgent.java2
-rw-r--r--services/java/com/android/server/WifiService.java1
-rw-r--r--services/java/com/android/server/accessibility/AccessibilityManagerService.java84
-rw-r--r--services/java/com/android/server/am/ActivityManagerService.java3
-rw-r--r--services/java/com/android/server/connectivity/Vpn.java63
-rw-r--r--services/java/com/android/server/usb/UsbDeviceManager.java35
-rw-r--r--services/surfaceflinger/DisplayHardware/DisplayHardware.cpp5
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp32
-rw-r--r--services/surfaceflinger/SurfaceFlinger.h7
-rw-r--r--voip/java/com/android/server/sip/SipService.java51
-rw-r--r--wifi/java/android/net/wifi/WifiStateMachine.java2
-rw-r--r--wifi/java/android/net/wifi/WifiWatchdogService.java (renamed from services/java/com/android/server/WifiWatchdogService.java)9
273 files changed, 2480 insertions, 1113 deletions
diff --git a/Android.mk b/Android.mk
index c2d4abc..9fbdde7 100644
--- a/Android.mk
+++ b/Android.mk
@@ -450,7 +450,9 @@ web_docs_sample_code_flags := \
-samplecode $(sample_dir)/VoicemailProviderDemo \
resources/samples/VoicemailProviderDemo "Voicemail Provider Demo" \
-samplecode $(sample_dir)/XmlAdapters \
- resources/samples/XmlAdapters "XML Adapters"
+ resources/samples/XmlAdapters "XML Adapters" \
+ -samplecode $(sample_dir)/TtsEngine \
+ resources/samples/TtsEngine "Text To Speech Engine"
## SDK version identifiers used in the published docs
# major[.minor] version for current SDK. (full releases only)
diff --git a/api/current.txt b/api/current.txt
index d009a64..9ad7b4e 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -183,14 +183,14 @@ 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/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 1ec7a96..eee14fb 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -2013,15 +2013,10 @@ 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 8af78fa..087f83c 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 63f3258..dce0a97 100644
--- a/core/java/android/app/backup/BackupAgent.java
+++ b/core/java/android/app/backup/BackupAgent.java
@@ -20,13 +20,22 @@ import android.app.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 3b70e19..d7f1c9f 100644
--- a/core/java/android/app/backup/FullBackup.java
+++ b/core/java/android/app/backup/FullBackup.java
@@ -16,6 +16,9 @@
package android.app.backup;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
import android.os.ParcelFileDescriptor;
import android.util.Log;
@@ -29,7 +32,8 @@ 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 df1c363..faea76a 100644
--- a/core/java/android/app/backup/FullBackupAgent.java
+++ b/core/java/android/app/backup/FullBackupAgent.java
@@ -16,210 +16,26 @@
package android.app.backup;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.os.Environment;
import android.os.ParcelFileDescriptor;
-import android.util.Log;
-
-import libcore.io.Libcore;
-import libcore.io.ErrnoException;
-import libcore.io.OsConstants;
-import libcore.io.StructStat;
-
-import java.io.File;
import java.io.IOException;
-import java.util.HashSet;
-import java.util.LinkedList;
/**
- * Backs up an application's entire /data/data/&lt;package&gt;/... file system. This
- * class is used by the desktop full backup mechanism and is not intended for direct
- * use by applications.
+ * Simple concrete class that merely provides the default BackupAgent full backup/restore
+ * implementations for applications that do not supply their own.
*
* {@hide}
*/
public class FullBackupAgent extends BackupAgent {
- // !!! TODO: turn off debugging
- private static final String TAG = "FullBackupAgent";
- private static final boolean DEBUG = true;
-
- PackageManager mPm;
-
- private String mMainDir;
- private String mFilesDir;
- private String mDatabaseDir;
- private String mSharedPrefsDir;
- private String mCacheDir;
- private String mLibDir;
-
- private File NULL_FILE;
-
- @Override
- public void onCreate() {
- NULL_FILE = new File("/dev/null");
-
- mPm = getPackageManager();
- try {
- ApplicationInfo appInfo = mPm.getApplicationInfo(getPackageName(), 0);
- mMainDir = new File(appInfo.dataDir).getAbsolutePath();
- } catch (PackageManager.NameNotFoundException e) {
- Log.e(TAG, "Unable to find package " + getPackageName());
- throw new RuntimeException(e);
- }
-
- mFilesDir = getFilesDir().getAbsolutePath();
- mDatabaseDir = getDatabasePath("foo").getParentFile().getAbsolutePath();
- mSharedPrefsDir = getSharedPrefsFile("foo").getParentFile().getAbsolutePath();
- mCacheDir = getCacheDir().getAbsolutePath();
-
- ApplicationInfo app = getApplicationInfo();
- mLibDir = (app.nativeLibraryDir != null)
- ? new File(app.nativeLibraryDir).getAbsolutePath()
- : null;
- }
-
@Override
public void onBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
ParcelFileDescriptor newState) throws IOException {
- // Filters, the scan queue, and the set of resulting entities
- HashSet<String> filterSet = new HashSet<String>();
- String packageName = getPackageName();
-
- // Okay, start with the app's root tree, but exclude all of the canonical subdirs
- if (mLibDir != null) {
- filterSet.add(mLibDir);
- }
- filterSet.add(mCacheDir);
- filterSet.add(mDatabaseDir);
- filterSet.add(mSharedPrefsDir);
- filterSet.add(mFilesDir);
- processTree(packageName, FullBackup.ROOT_TREE_TOKEN, mMainDir, filterSet, data);
-
- // Now do the same for the files dir, db dir, and shared prefs dir
- filterSet.add(mMainDir);
- filterSet.remove(mFilesDir);
- processTree(packageName, FullBackup.DATA_TREE_TOKEN, mFilesDir, filterSet, data);
-
- filterSet.add(mFilesDir);
- filterSet.remove(mDatabaseDir);
- processTree(packageName, FullBackup.DATABASE_TREE_TOKEN, mDatabaseDir, filterSet, data);
-
- filterSet.add(mDatabaseDir);
- filterSet.remove(mSharedPrefsDir);
- processTree(packageName, FullBackup.SHAREDPREFS_TREE_TOKEN, mSharedPrefsDir, filterSet, data);
+ // Doesn't do incremental backup/restore
}
- // Scan the dir tree (if it actually exists) and process each entry we find. If the
- // 'excludes' parameter is non-null, it is consulted each time a new file system entity
- // is visited to see whether that entity (and its subtree, if appropriate) should be
- // omitted from the backup process.
- protected void processTree(String packageName, String domain, String rootPath,
- HashSet<String> excludes, BackupDataOutput data) {
- File rootFile = new File(rootPath);
- if (rootFile.exists()) {
- LinkedList<File> scanQueue = new LinkedList<File>();
- scanQueue.add(rootFile);
-
- while (scanQueue.size() > 0) {
- File file = scanQueue.remove(0);
- String filePath = file.getAbsolutePath();
-
- // prune this subtree?
- if (excludes != null && excludes.contains(filePath)) {
- continue;
- }
-
- // If it's a directory, enqueue its contents for scanning.
- try {
- StructStat stat = Libcore.os.lstat(filePath);
- if (OsConstants.S_ISLNK(stat.st_mode)) {
- if (DEBUG) Log.i(TAG, "Symlink (skipping)!: " + file);
- continue;
- } else if (OsConstants.S_ISDIR(stat.st_mode)) {
- File[] contents = file.listFiles();
- if (contents != null) {
- for (File entry : contents) {
- scanQueue.add(0, entry);
- }
- }
- }
- } catch (ErrnoException e) {
- if (DEBUG) Log.w(TAG, "Error scanning file " + file + " : " + e);
- continue;
- }
-
- // Finally, back this file up before proceeding
- FullBackup.backupToTar(packageName, domain, null, rootPath, filePath, data);
- }
- }
- }
-
- @Override
- void onSaveApk(BackupDataOutput data) {
- ApplicationInfo app = getApplicationInfo();
- if (DEBUG) Log.i(TAG, "APK flags: system=" + ((app.flags & ApplicationInfo.FLAG_SYSTEM) != 0)
- + " updated=" + ((app.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0)
- + " locked=" + ((app.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0) );
- if (DEBUG) Log.i(TAG, "codepath: " + getPackageCodePath());
-
- // Forward-locked apps, system-bundled .apks, etc are filtered out before we get here
- final String pkgName = getPackageName();
- final String apkDir = new File(getPackageCodePath()).getParent();
- FullBackup.backupToTar(pkgName, FullBackup.APK_TREE_TOKEN, null,
- apkDir, getPackageCodePath(), data);
-
- // Save associated .obb content if it exists and we did save the apk
- // check for .obb and save those too
- final File obbDir = Environment.getExternalStorageAppObbDirectory(pkgName);
- if (obbDir != null) {
- if (DEBUG) Log.i(TAG, "obb dir: " + obbDir.getAbsolutePath());
- File[] obbFiles = obbDir.listFiles();
- if (obbFiles != null) {
- final String obbDirName = obbDir.getAbsolutePath();
- for (File obb : obbFiles) {
- FullBackup.backupToTar(pkgName, FullBackup.OBB_TREE_TOKEN, null,
- obbDirName, obb.getAbsolutePath(), data);
- }
- }
- }
- }
-
- /**
- * Dummy -- We're never used for restore of an incremental dataset
- */
@Override
public void onRestore(BackupDataInput data, int appVersionCode, ParcelFileDescriptor newState)
throws IOException {
- }
-
- /**
- * Restore the described file from the given pipe.
- */
- @Override
- public void onRestoreFile(ParcelFileDescriptor data, long size,
- int type, String domain, String relpath, long mode, long mtime)
- throws IOException {
- String basePath = null;
- File outFile = null;
-
- if (DEBUG) Log.d(TAG, "onRestoreFile() size=" + size + " type=" + type
- + " domain=" + domain + " relpath=" + relpath + " mode=" + mode
- + " mtime=" + mtime);
-
- // Parse out the semantic domains into the correct physical location
- if (domain.equals(FullBackup.DATA_TREE_TOKEN)) basePath = mFilesDir;
- else if (domain.equals(FullBackup.DATABASE_TREE_TOKEN)) basePath = mDatabaseDir;
- else if (domain.equals(FullBackup.ROOT_TREE_TOKEN)) basePath = mMainDir;
- else if (domain.equals(FullBackup.SHAREDPREFS_TREE_TOKEN)) basePath = mSharedPrefsDir;
-
- // Not a supported output location? We need to consume the data
- // anyway, so send it to /dev/null
- outFile = (basePath != null) ? new File(basePath, relpath) : null;
- if (DEBUG) Log.i(TAG, "[" + domain + " : " + relpath + "] mapped to " + outFile.getPath());
-
- // Now that we've figured out where the data goes, send it on its way
- FullBackup.restoreToFile(data, size, type, mode, mtime, outFile, true);
+ // Doesn't do incremental backup/restore
}
}
diff --git a/core/java/android/app/backup/FullBackupDataOutput.java b/core/java/android/app/backup/FullBackupDataOutput.java
new file mode 100644
index 0000000..99dab1f
--- /dev/null
+++ b/core/java/android/app/backup/FullBackupDataOutput.java
@@ -0,0 +1,21 @@
+package android.app.backup;
+
+import android.os.ParcelFileDescriptor;
+
+/**
+ * Provides the interface through which a {@link BackupAgent} writes entire files
+ * to a full backup data set, via its {@link BackupAgent#onFullBackup(FullBackupDataOutput)}
+ * method.
+ */
+public class FullBackupDataOutput {
+ // Currently a name-scoping shim around BackupDataOutput
+ private BackupDataOutput mData;
+
+ /** @hide */
+ public FullBackupDataOutput(ParcelFileDescriptor fd) {
+ mData = new BackupDataOutput(fd.getFileDescriptor());
+ }
+
+ /** @hide */
+ public BackupDataOutput getData() { return mData; }
+}
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 454cb31..ddb6ef0 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -91,15 +91,6 @@ public 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 208869b..53d6bb1 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 4e33938..f2d84eb 100644
--- a/services/java/com/android/server/DnsPinger.java
+++ b/core/java/android/net/DnsPinger.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.server;
+package android.net;
import android.content.Context;
import android.net.ConnectivityManager;
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index 57f5967..d6f5643 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -23,6 +23,7 @@ import android.net.ProxyProperties;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
+import com.android.internal.net.LegacyVpnInfo;
import com.android.internal.net.VpnConfig;
/**
@@ -105,5 +106,7 @@ interface IConnectivityManager
ParcelFileDescriptor establishVpn(in VpnConfig config);
- void doLegacyVpn(in VpnConfig config, in String[] racoon, in String[] mtpd);
+ void startLegacyVpn(in VpnConfig config, in String[] racoon, in String[] mtpd);
+
+ LegacyVpnInfo getLegacyVpnInfo();
}
diff --git a/core/java/android/net/http/SslCertificate.java b/core/java/android/net/http/SslCertificate.java
index f35002a..fe6d4eb 100644
--- a/core/java/android/net/http/SslCertificate.java
+++ b/core/java/android/net/http/SslCertificate.java
@@ -23,13 +23,20 @@ import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;
+import java.io.ByteArrayInputStream;
+import java.math.BigInteger;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Vector;
-import com.android.org.bouncycastle.asn1.DERObjectIdentifier;
import com.android.org.bouncycastle.asn1.x509.X509Name;
/**
@@ -45,22 +52,31 @@ public class SslCertificate {
/**
* Name of the entity this certificate is issued to
*/
- private DName mIssuedTo;
+ private final DName mIssuedTo;
/**
* Name of the entity this certificate is issued by
*/
- private DName mIssuedBy;
+ private final DName mIssuedBy;
/**
* Not-before date from the validity period
*/
- private Date mValidNotBefore;
+ private final Date mValidNotBefore;
/**
* Not-after date from the validity period
*/
- private Date mValidNotAfter;
+ private final Date mValidNotAfter;
+
+ /**
+ * The original source certificate, if available.
+ *
+ * TODO If deprecated constructors are removed, this should always
+ * be available, and saveState and restoreState can be simplified
+ * to be unconditional.
+ */
+ private final X509Certificate mX509Certificate;
/**
* Bundle key names
@@ -69,6 +85,7 @@ public class SslCertificate {
private static final String ISSUED_BY = "issued-by";
private static final String VALID_NOT_BEFORE = "valid-not-before";
private static final String VALID_NOT_AFTER = "valid-not-after";
+ private static final String X509_CERTIFICATE = "x509-certificate";
/**
* Saves the certificate state to a bundle
@@ -76,18 +93,21 @@ public class SslCertificate {
* @return A bundle with the certificate stored in it or null if fails
*/
public static Bundle saveState(SslCertificate certificate) {
- Bundle bundle = null;
-
- if (certificate != null) {
- bundle = new Bundle();
-
- bundle.putString(ISSUED_TO, certificate.getIssuedTo().getDName());
- bundle.putString(ISSUED_BY, certificate.getIssuedBy().getDName());
-
- bundle.putString(VALID_NOT_BEFORE, certificate.getValidNotBefore());
- bundle.putString(VALID_NOT_AFTER, certificate.getValidNotAfter());
+ if (certificate == null) {
+ return null;
+ }
+ Bundle bundle = new Bundle();
+ bundle.putString(ISSUED_TO, certificate.getIssuedTo().getDName());
+ bundle.putString(ISSUED_BY, certificate.getIssuedBy().getDName());
+ bundle.putString(VALID_NOT_BEFORE, certificate.getValidNotBefore());
+ bundle.putString(VALID_NOT_AFTER, certificate.getValidNotAfter());
+ X509Certificate x509Certificate = certificate.mX509Certificate;
+ if (x509Certificate != null) {
+ try {
+ bundle.putByteArray(X509_CERTIFICATE, x509Certificate.getEncoded());
+ } catch (CertificateEncodingException ignored) {
+ }
}
-
return bundle;
}
@@ -97,15 +117,27 @@ public class SslCertificate {
* @return The SSL certificate stored in the bundle or null if fails
*/
public static SslCertificate restoreState(Bundle bundle) {
- if (bundle != null) {
- return new SslCertificate(
- bundle.getString(ISSUED_TO),
- bundle.getString(ISSUED_BY),
- bundle.getString(VALID_NOT_BEFORE),
- bundle.getString(VALID_NOT_AFTER));
+ if (bundle == null) {
+ return null;
}
-
- return null;
+ X509Certificate x509Certificate;
+ byte[] bytes = bundle.getByteArray(X509_CERTIFICATE);
+ if (bytes == null) {
+ x509Certificate = null;
+ } else {
+ try {
+ CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
+ Certificate cert = certFactory.generateCertificate(new ByteArrayInputStream(bytes));
+ x509Certificate = (X509Certificate) cert;
+ } catch (CertificateException e) {
+ x509Certificate = null;
+ }
+ }
+ return new SslCertificate(bundle.getString(ISSUED_TO),
+ bundle.getString(ISSUED_BY),
+ parseDate(bundle.getString(VALID_NOT_BEFORE)),
+ parseDate(bundle.getString(VALID_NOT_AFTER)),
+ x509Certificate);
}
/**
@@ -121,7 +153,7 @@ public class SslCertificate {
@Deprecated
public SslCertificate(
String issuedTo, String issuedBy, String validNotBefore, String validNotAfter) {
- this(issuedTo, issuedBy, parseDate(validNotBefore), parseDate(validNotAfter));
+ this(issuedTo, issuedBy, parseDate(validNotBefore), parseDate(validNotAfter), null);
}
/**
@@ -135,10 +167,7 @@ public class SslCertificate {
@Deprecated
public SslCertificate(
String issuedTo, String issuedBy, Date validNotBefore, Date validNotAfter) {
- mIssuedTo = new DName(issuedTo);
- mIssuedBy = new DName(issuedBy);
- mValidNotBefore = cloneDate(validNotBefore);
- mValidNotAfter = cloneDate(validNotAfter);
+ this(issuedTo, issuedBy, validNotBefore, validNotAfter, null);
}
/**
@@ -149,7 +178,19 @@ public class SslCertificate {
this(certificate.getSubjectDN().getName(),
certificate.getIssuerDN().getName(),
certificate.getNotBefore(),
- certificate.getNotAfter());
+ certificate.getNotAfter(),
+ certificate);
+ }
+
+ private SslCertificate(
+ String issuedTo, String issuedBy,
+ Date validNotBefore, Date validNotAfter,
+ X509Certificate x509Certificate) {
+ mIssuedTo = new DName(issuedTo);
+ mIssuedBy = new DName(issuedBy);
+ mValidNotBefore = cloneDate(validNotBefore);
+ mValidNotAfter = cloneDate(validNotAfter);
+ mX509Certificate = x509Certificate;
}
/**
@@ -205,6 +246,54 @@ public class SslCertificate {
}
/**
+ * Convenience for UI presentation, not intended as public API.
+ */
+ private static String getSerialNumber(X509Certificate x509Certificate) {
+ if (x509Certificate == null) {
+ return "";
+ }
+ BigInteger serialNumber = x509Certificate.getSerialNumber();
+ if (serialNumber == null) {
+ return "";
+ }
+ return fingerprint(serialNumber.toByteArray());
+ }
+
+ /**
+ * Convenience for UI presentation, not intended as public API.
+ */
+ private static String getDigest(X509Certificate x509Certificate, String algorithm) {
+ if (x509Certificate == null) {
+ return "";
+ }
+ try {
+ byte[] bytes = x509Certificate.getEncoded();
+ MessageDigest md = MessageDigest.getInstance(algorithm);
+ byte[] digest = md.digest(bytes);
+ return fingerprint(digest);
+ } catch (CertificateEncodingException ignored) {
+ return "";
+ } catch (NoSuchAlgorithmException ignored) {
+ return "";
+ }
+ }
+
+ private static final String fingerprint(byte[] bytes) {
+ if (bytes == null) {
+ return "";
+ }
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < bytes.length; i++) {
+ byte b = bytes[i];
+ IntegralToString.appendByteAsHex(sb, b, true);
+ if (i+1 != bytes.length) {
+ sb.append(':');
+ }
+ }
+ return sb.toString();
+ }
+
+ /**
* @return A string representation of this certificate for debugging
*/
public String toString() {
@@ -338,7 +427,6 @@ public class SslCertificate {
* Inflates the SSL certificate view (helper method).
* @return The resultant certificate view with issued-to, issued-by,
* issued-on, expires-on, and possibly other fields set.
- * If the input certificate is null, returns null.
*
* @hide Used by Browser and Settings
*/
@@ -352,33 +440,42 @@ public class SslCertificate {
SslCertificate.DName issuedTo = getIssuedTo();
if (issuedTo != null) {
((TextView) certificateView.findViewById(com.android.internal.R.id.to_common))
- .setText(issuedTo.getCName());
+ .setText(issuedTo.getCName());
((TextView) certificateView.findViewById(com.android.internal.R.id.to_org))
- .setText(issuedTo.getOName());
+ .setText(issuedTo.getOName());
((TextView) certificateView.findViewById(com.android.internal.R.id.to_org_unit))
- .setText(issuedTo.getUName());
+ .setText(issuedTo.getUName());
}
+ // serial number:
+ ((TextView) certificateView.findViewById(com.android.internal.R.id.serial_number))
+ .setText(getSerialNumber(mX509Certificate));
// issued by:
SslCertificate.DName issuedBy = getIssuedBy();
if (issuedBy != null) {
((TextView) certificateView.findViewById(com.android.internal.R.id.by_common))
- .setText(issuedBy.getCName());
+ .setText(issuedBy.getCName());
((TextView) certificateView.findViewById(com.android.internal.R.id.by_org))
- .setText(issuedBy.getOName());
+ .setText(issuedBy.getOName());
((TextView) certificateView.findViewById(com.android.internal.R.id.by_org_unit))
- .setText(issuedBy.getUName());
+ .setText(issuedBy.getUName());
}
// issued on:
String issuedOn = formatCertificateDate(context, getValidNotBeforeDate());
((TextView) certificateView.findViewById(com.android.internal.R.id.issued_on))
- .setText(issuedOn);
+ .setText(issuedOn);
// expires on:
String expiresOn = formatCertificateDate(context, getValidNotAfterDate());
((TextView) certificateView.findViewById(com.android.internal.R.id.expires_on))
- .setText(expiresOn);
+ .setText(expiresOn);
+
+ // fingerprints:
+ ((TextView) certificateView.findViewById(com.android.internal.R.id.sha256_fingerprint))
+ .setText(getDigest(mX509Certificate, "SHA256"));
+ ((TextView) certificateView.findViewById(com.android.internal.R.id.sha1_fingerprint))
+ .setText(getDigest(mX509Certificate, "SHA1"));
return certificateView;
}
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index 05e39ac..673b187 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -522,6 +522,9 @@ 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/MediaStore.java b/core/java/android/provider/MediaStore.java
index 3bc1348..f799af3 100644
--- a/core/java/android/provider/MediaStore.java
+++ b/core/java/android/provider/MediaStore.java
@@ -275,6 +275,14 @@ public final class MediaStore {
* @hide
*/
public static final String MEDIA_SCANNER_NEW_OBJECT_ID = "media_scanner_new_object_id";
+
+ /**
+ * Non-zero if the media file is drm-protected
+ * <P>Type: INTEGER (boolean)</P>
+ * @hide
+ */
+ public static final String IS_DRM = "is_drm";
+
}
/**
@@ -1124,19 +1132,19 @@ public final class MediaStore {
public static final String IS_PODCAST = "is_podcast";
/**
- * Non-zero id the audio file may be a ringtone
+ * Non-zero if the audio file may be a ringtone
* <P>Type: INTEGER (boolean)</P>
*/
public static final String IS_RINGTONE = "is_ringtone";
/**
- * Non-zero id the audio file may be an alarm
+ * Non-zero if the audio file may be an alarm
* <P>Type: INTEGER (boolean)</P>
*/
public static final String IS_ALARM = "is_alarm";
/**
- * Non-zero id the audio file may be a notification sound
+ * Non-zero if the audio file may be a notification sound
* <P>Type: INTEGER (boolean)</P>
*/
public static final String IS_NOTIFICATION = "is_notification";
diff --git a/core/java/android/provider/VoicemailContract.java b/core/java/android/provider/VoicemailContract.java
index aaa7701..d0712d5 100644
--- a/core/java/android/provider/VoicemailContract.java
+++ b/core/java/android/provider/VoicemailContract.java
@@ -54,18 +54,6 @@ public class VoicemailContract {
/** The authority used by the voicemail provider. */
public static final String AUTHORITY = "com.android.voicemail";
/**
- * URI to insert/retrieve all voicemails.
- * @deprecated
- */
- public static final Uri CONTENT_URI =
- Uri.parse("content://" + AUTHORITY + "/voicemail");
- /**
- * URI to insert/retrieve voicemails by a given voicemail source.
- * @deprecated
- */
- public static final Uri CONTENT_URI_SOURCE =
- Uri.parse("content://" + AUTHORITY + "/voicemail/source/");
- /**
* Parameter key used in the URI to specify the voicemail source package name.
* <p> This field must be set in all requests that originate from a voicemail source.
*/
@@ -82,9 +70,10 @@ public class VoicemailContract {
public static final String EXTRA_SELF_CHANGE = "com.android.voicemail.extra.SELF_CHANGE";
/**
- * The mime type for a collection of voicemails.
- * @deprecated */
- public static final String DIR_TYPE = "vnd.android.cursor.dir/voicemails";
+ * Name of the source package field, which must be same across all voicemail related tables.
+ * @hide
+ */
+ public static final String SOURCE_PACKAGE_FIELD = "source_package";
/** Defines fields exposed through the /voicemail path of this content provider. */
public static final class Voicemails implements BaseColumns {
@@ -92,12 +81,9 @@ public class VoicemailContract {
private Voicemails() {
}
- /** URI to insert/retrieve voicemails by a given voicemail source. */
+ /** URI to insert/retrieve voicemails. */
public static final Uri CONTENT_URI =
Uri.parse("content://" + AUTHORITY + "/voicemail");
- /** URI to insert/retrieve voicemails by a given voicemail source. */
- public static final Uri CONTENT_URI_SOURCE =
- Uri.parse("content://" + AUTHORITY + "/voicemail/source/");
/** The mime type for a collection of voicemails. */
public static final String DIR_TYPE = "vnd.android.cursor.dir/voicemails";
@@ -139,7 +125,7 @@ public class VoicemailContract {
* Package name of the source application that inserted the voicemail.
* <P>Type: TEXT</P>
*/
- public static final String SOURCE_PACKAGE = "source_package";
+ public static final String SOURCE_PACKAGE = SOURCE_PACKAGE_FIELD;
/**
* Application-specific data available to the source application that
* inserted the voicemail. This is typically used to store the source
@@ -192,7 +178,7 @@ public class VoicemailContract {
* The package name of the voicemail source. There can only be a one entry per source.
* <P>Type: TEXT</P>
*/
- public static final String SOURCE_PACKAGE = "source_package";
+ public static final String SOURCE_PACKAGE = SOURCE_PACKAGE_FIELD;
/**
* The URI to call to invoke source specific voicemail settings screen. On a user request
* to setup voicemail an intent with action VIEW with this URI will be fired by the system.
diff --git a/core/java/android/speech/tts/AudioPlaybackHandler.java b/core/java/android/speech/tts/AudioPlaybackHandler.java
index a3686b7..c7603ee 100644
--- a/core/java/android/speech/tts/AudioPlaybackHandler.java
+++ b/core/java/android/speech/tts/AudioPlaybackHandler.java
@@ -74,6 +74,12 @@ class AudioPlaybackHandler {
removeMessages(token);
if (token.getType() == MessageParams.TYPE_SYNTHESIS) {
+ AudioTrack current = ((SynthesisMessageParams) token).getAudioTrack();
+ if (current != null) {
+ // Stop the current audio track if it's still playing.
+ // The audio track is thread safe in this regard.
+ current.stop();
+ }
mQueue.add(new ListEntry(SYNTHESIS_DONE, token, HIGH_PRIORITY));
} else {
final MessageParams current = getCurrentParams();
@@ -393,9 +399,10 @@ class AudioPlaybackHandler {
try {
if (audioTrack != null) {
- audioTrack.flush();
- audioTrack.stop();
if (DBG) Log.d(TAG, "Releasing audio track [" + audioTrack.hashCode() + "]");
+ // The last call to AudioTrack.write( ) will return only after
+ // all data from the audioTrack has been sent to the mixer, so
+ // it's safe to release at this point.
audioTrack.release();
}
} finally {
diff --git a/core/java/android/view/inputmethod/InputMethodSubtype.java b/core/java/android/view/inputmethod/InputMethodSubtype.java
index 9d84c3e..4a98336 100644
--- a/core/java/android/view/inputmethod/InputMethodSubtype.java
+++ b/core/java/android/view/inputmethod/InputMethodSubtype.java
@@ -160,10 +160,10 @@ public final class InputMethodSubtype implements Parcelable {
if (mSubtypeNameResId == 0) {
return localeStr;
}
- final String subtypeName = context.getPackageManager().getText(
- packageName, mSubtypeNameResId, appInfo).toString();
+ final CharSequence subtypeName = context.getPackageManager().getText(
+ packageName, mSubtypeNameResId, appInfo);
if (!TextUtils.isEmpty(subtypeName)) {
- return String.format(subtypeName, localeStr);
+ return String.format(subtypeName.toString(), localeStr);
} else {
return localeStr;
}
diff --git a/core/java/android/webkit/BrowserFrame.java b/core/java/android/webkit/BrowserFrame.java
index 79a5aff..5aa60f4 100644
--- a/core/java/android/webkit/BrowserFrame.java
+++ b/core/java/android/webkit/BrowserFrame.java
@@ -50,8 +50,10 @@ import java.security.cert.CertificateEncodingException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.HashMap;
-import java.util.Map;
+import java.util.HashSet;
import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
import org.apache.harmony.security.provider.cert.X509CertImpl;
@@ -86,7 +88,8 @@ class BrowserFrame extends Handler {
private boolean mIsMainFrame;
// Attached Javascript interfaces
- private Map<String, Object> mJSInterfaceMap;
+ private Map<String, Object> mJavaScriptObjects;
+ private Set<Object> mRemovedJavaScriptObjects;
// Key store handler when Chromium HTTP stack is used.
private KeyStoreHandler mKeyStoreHandler = null;
@@ -229,10 +232,11 @@ class BrowserFrame extends Handler {
}
sConfigCallback.addHandler(this);
- mJSInterfaceMap = javascriptInterfaces;
- if (mJSInterfaceMap == null) {
- mJSInterfaceMap = new HashMap<String, Object>();
+ mJavaScriptObjects = javascriptInterfaces;
+ if (mJavaScriptObjects == null) {
+ mJavaScriptObjects = new HashMap<String, Object>();
}
+ mRemovedJavaScriptObjects = new HashSet<Object>();
mSettings = settings;
mContext = context;
@@ -241,7 +245,7 @@ class BrowserFrame extends Handler {
mWebViewCore = w;
mSearchBox = new SearchBoxImpl(mWebViewCore, mCallbackProxy);
- mJSInterfaceMap.put(SearchBoxImpl.JS_INTERFACE_NAME, mSearchBox);
+ mJavaScriptObjects.put(SearchBoxImpl.JS_INTERFACE_NAME, mSearchBox);
AssetManager am = context.getAssets();
nativeCreateFrame(w, am, proxy.getBackForwardList());
@@ -598,15 +602,16 @@ class BrowserFrame extends Handler {
* We should re-attach any attached js interfaces.
*/
private void windowObjectCleared(int nativeFramePointer) {
- Iterator<String> iter = mJSInterfaceMap.keySet().iterator();
+ Iterator<String> iter = mJavaScriptObjects.keySet().iterator();
while (iter.hasNext()) {
String interfaceName = iter.next();
- Object object = mJSInterfaceMap.get(interfaceName);
+ Object object = mJavaScriptObjects.get(interfaceName);
if (object != null) {
nativeAddJavascriptInterface(nativeFramePointer,
- mJSInterfaceMap.get(interfaceName), interfaceName);
+ mJavaScriptObjects.get(interfaceName), interfaceName);
}
}
+ mRemovedJavaScriptObjects.clear();
stringByEvaluatingJavaScriptFromString(SearchBoxImpl.JS_BRIDGE);
}
@@ -632,12 +637,15 @@ class BrowserFrame extends Handler {
assert obj != null;
removeJavascriptInterface(interfaceName);
- mJSInterfaceMap.put(interfaceName, obj);
+ mJavaScriptObjects.put(interfaceName, obj);
}
public void removeJavascriptInterface(String interfaceName) {
- if (mJSInterfaceMap.containsKey(interfaceName)) {
- mJSInterfaceMap.remove(interfaceName);
+ // We keep a reference to the removed object because the native side holds only a weak
+ // reference and we need to allow the object to continue to be used until the page has been
+ // navigated.
+ if (mJavaScriptObjects.containsKey(interfaceName)) {
+ mRemovedJavaScriptObjects.add(mJavaScriptObjects.remove(interfaceName));
}
}
diff --git a/core/java/android/webkit/CallbackProxy.java b/core/java/android/webkit/CallbackProxy.java
index f7d55f6..0294e3f 100644
--- a/core/java/android/webkit/CallbackProxy.java
+++ b/core/java/android/webkit/CallbackProxy.java
@@ -119,6 +119,7 @@ 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 57c7b03..5075302 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 480f5d7..61fb2ce 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 9f632d1..7ba86a5 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -1971,9 +1971,14 @@ public class WebView extends AbsoluteLayout
}
/**
- * Load the given data into the WebView using a 'data' scheme URL. Content
- * loaded in this way does not have the ability to load content from the
- * network.
+ * Load the given data into the WebView using a 'data' scheme URL.
+ * <p>
+ * Note that JavaScript's same origin policy means that script running in a
+ * page loaded using this method will be unable to access content loaded
+ * using any scheme other than 'data', including 'http(s)'. To avoid this
+ * restriction, use {@link
+ * #loadDataWithBaseURL(String,String,String,String,String)
+ * loadDataWithBaseURL()} with an appropriate base URL.
* <p>
* If the value of the encoding parameter is 'base64', then the data must
* be encoded as base64. Otherwise, the data must use ASCII encoding for
@@ -2000,21 +2005,26 @@ public class WebView extends AbsoluteLayout
}
/**
- * Load the given data into the WebView, use the provided URL as the base
- * URL for the content. The base URL is the URL that represents the page
- * that is loaded through this interface. As such, it is used to resolve any
- * relative URLs. The historyUrl is used for the history entry.
+ * Load the given data into the WebView, using baseUrl as the base URL for
+ * the content. The base URL is used both to resolve relative URLs and when
+ * applying JavaScript's same origin policy. The historyUrl is used for the
+ * history entry.
* <p>
* Note that content specified in this way can access local device files
* (via 'file' scheme URLs) only if baseUrl specifies a scheme other than
* 'http', 'https', 'ftp', 'ftps', 'about' or 'javascript'.
- * @param baseUrl Url to resolve relative paths with, if null defaults to
- * "about:blank"
+ * <p>
+ * If the base URL uses the data scheme, this method is equivalent to
+ * calling {@link #loadData(String,String,String) loadData()} and the
+ * historyUrl is ignored.
+ * @param baseUrl URL to use as the page's base URL. If null defaults to
+ * 'about:blank'
* @param data A String of data in the given encoding.
- * @param mimeType The MIMEType of the data. i.e. text/html. If null,
- * defaults to "text/html"
- * @param encoding The encoding of the data. i.e. utf-8, us-ascii
- * @param historyUrl URL to use as the history entry. Can be null.
+ * @param mimeType The MIMEType of the data, e.g. 'text/html'. If null,
+ * defaults to 'text/html'.
+ * @param encoding The encoding of the data.
+ * @param historyUrl URL to use as the history entry, if null defaults to
+ * 'about:blank'.
*/
public void loadDataWithBaseURL(String baseUrl, String data,
String mimeType, String encoding, String historyUrl) {
diff --git a/core/java/android/webkit/WebViewFragment.java b/core/java/android/webkit/WebViewFragment.java
index 466f174..852878b 100644
--- a/core/java/android/webkit/WebViewFragment.java
+++ b/core/java/android/webkit/WebViewFragment.java
@@ -30,6 +30,7 @@ import android.webkit.WebView;
*/
public class WebViewFragment extends Fragment {
private WebView mWebView;
+ private boolean mIsWebViewAvailable;
public WebViewFragment() {
}
@@ -40,7 +41,11 @@ public class WebViewFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
+ if (mWebView != null) {
+ mWebView.destroy();
+ }
mWebView = new WebView(getActivity());
+ mIsWebViewAvailable = true;
return mWebView;
}
@@ -63,19 +68,31 @@ public class WebViewFragment extends Fragment {
}
/**
- * Called when the view has been detached from the fragment. Destroys the WebView.
+ * Called when the WebView has been detached from the fragment.
+ * The WebView is no longer available after this time.
*/
@Override
public void onDestroyView() {
- mWebView.destroy();
- mWebView = null;
+ mIsWebViewAvailable = false;
super.onDestroyView();
}
/**
+ * Called when the fragment is no longer in use. Destroys the internal state of the WebView.
+ */
+ @Override
+ public void onDestroy() {
+ if (mWebView != null) {
+ mWebView.destroy();
+ mWebView = null;
+ }
+ super.onDestroy();
+ }
+
+ /**
* Gets the WebView.
*/
public WebView getWebView() {
- return mWebView;
+ return mIsWebViewAvailable ? mWebView : null;
}
}
diff --git a/core/java/android/webkit/ZoomManager.java b/core/java/android/webkit/ZoomManager.java
index 7d43e94..252fc8f 100644
--- a/core/java/android/webkit/ZoomManager.java
+++ b/core/java/android/webkit/ZoomManager.java
@@ -1111,6 +1111,12 @@ 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 fc8bce8..427fd3e 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 c91f1a6..772e8e9 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/net/LegacyVpnInfo.aidl b/core/java/com/android/internal/net/LegacyVpnInfo.aidl
new file mode 100644
index 0000000..0ca2627
--- /dev/null
+++ b/core/java/com/android/internal/net/LegacyVpnInfo.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.net;
+
+parcelable LegacyVpnInfo;
diff --git a/core/java/com/android/internal/net/LegacyVpnInfo.java b/core/java/com/android/internal/net/LegacyVpnInfo.java
new file mode 100644
index 0000000..b620aba
--- /dev/null
+++ b/core/java/com/android/internal/net/LegacyVpnInfo.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.net;
+
+import android.app.PendingIntent;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * A simple container used to carry information of the ongoing legacy VPN.
+ * Internal use only.
+ *
+ * @hide
+ */
+public class LegacyVpnInfo implements Parcelable {
+ public static final int STATE_DISCONNECTED = 0;
+ public static final int STATE_INITIALIZING = 1;
+ public static final int STATE_CONNECTING = 2;
+ public static final int STATE_CONNECTED = 3;
+ public static final int STATE_TIMEOUT = 4;
+ public static final int STATE_FAILED = 5;
+
+ public String key;
+ public int state = -1;
+ public PendingIntent intent;
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeString(key);
+ out.writeInt(state);
+ out.writeParcelable(intent, flags);
+ }
+
+ public static final Parcelable.Creator<LegacyVpnInfo> CREATOR =
+ new Parcelable.Creator<LegacyVpnInfo>() {
+ @Override
+ public LegacyVpnInfo createFromParcel(Parcel in) {
+ LegacyVpnInfo info = new LegacyVpnInfo();
+ info.key = in.readString();
+ info.state = in.readInt();
+ info.intent = in.readParcelable(null);
+ return info;
+ }
+
+ @Override
+ public LegacyVpnInfo[] newArray(int size) {
+ return new LegacyVpnInfo[size];
+ }
+ };
+}
diff --git a/core/java/com/android/internal/net/VpnConfig.java b/core/java/com/android/internal/net/VpnConfig.java
index 003c244..d36be10 100644
--- a/core/java/com/android/internal/net/VpnConfig.java
+++ b/core/java/com/android/internal/net/VpnConfig.java
@@ -21,7 +21,6 @@ import android.content.Context;
import android.content.Intent;
import android.os.Parcel;
import android.os.Parcelable;
-import android.os.SystemClock;
import java.util.List;
@@ -43,14 +42,14 @@ public class VpnConfig implements Parcelable {
return intent;
}
- public static PendingIntent getIntentForNotification(Context context, VpnConfig config) {
- config.startTime = SystemClock.elapsedRealtime();
+ public static PendingIntent getIntentForStatusPanel(Context context, VpnConfig config) {
Intent intent = new Intent();
intent.setClassName("com.android.vpndialogs", "com.android.vpndialogs.ManageDialog");
intent.putExtra("config", config);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NO_HISTORY |
Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
- return PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
+ return PendingIntent.getActivity(context, 0, intent, (config == null) ?
+ PendingIntent.FLAG_NO_CREATE : PendingIntent.FLAG_CANCEL_CURRENT);
}
public String packagz;
diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java
index b872e22..7cb002c 100644
--- a/core/java/com/android/internal/os/ZygoteConnection.java
+++ b/core/java/com/android/internal/os/ZygoteConnection.java
@@ -328,8 +328,8 @@ 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 479788d..3b497e4 100644
--- a/core/java/com/android/internal/view/menu/ActionMenuItemView.java
+++ b/core/java/com/android/internal/view/menu/ActionMenuItemView.java
@@ -17,6 +17,7 @@
package com.android.internal.view.menu;
import android.content.Context;
+import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import android.util.AttributeSet;
@@ -38,17 +39,24 @@ 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 2fec9cd..b86eb13 100644
--- a/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
+++ b/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
@@ -19,8 +19,8 @@ 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 7b4f216..cfe9e59 100644
--- a/core/java/com/android/internal/view/menu/ActionMenuView.java
+++ b/core/java/com/android/internal/view/menu/ActionMenuView.java
@@ -30,12 +30,16 @@ 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 7b1dfb0..20b7d80 100644
--- a/core/java/com/android/internal/view/menu/MenuItemImpl.java
+++ b/core/java/com/android/internal/view/menu/MenuItemImpl.java
@@ -506,6 +506,10 @@ 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 953328c..9fef2a9 100644
--- a/core/java/com/android/internal/widget/ActionBarContainer.java
+++ b/core/java/com/android/internal/widget/ActionBarContainer.java
@@ -19,6 +19,8 @@ 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/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 1a32060..49eaf19 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1418,7 +1418,6 @@
android:label="@string/android_system_label"
android:allowClearUserData="false"
android:backupAgent="com.android.server.SystemBackupAgent"
- android:fullBackupAgent="com.android.server.SystemBackupAgent"
android:killAfterRestore="false"
android:icon="@drawable/ic_launcher_android">
<activity android:name="com.android.internal.app.ChooserActivity"
diff --git a/core/res/res/drawable-hdpi/ab_bottom_solid_dark_holo.9.png b/core/res/res/drawable-hdpi/ab_bottom_solid_dark_holo.9.png
new file mode 100644
index 0000000..3ea6c44
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ab_bottom_solid_dark_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ab_bottom_solid_inverse_holo.9.png b/core/res/res/drawable-hdpi/ab_bottom_solid_inverse_holo.9.png
new file mode 100644
index 0000000..6c6fcd2
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ab_bottom_solid_inverse_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ab_bottom_solid_light_holo.9.png b/core/res/res/drawable-hdpi/ab_bottom_solid_light_holo.9.png
new file mode 100644
index 0000000..854631e
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ab_bottom_solid_light_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ab_bottom_transparent_dark_holo.9.png b/core/res/res/drawable-hdpi/ab_bottom_transparent_dark_holo.9.png
new file mode 100644
index 0000000..aef6142d
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ab_bottom_transparent_dark_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ab_bottom_transparent_light_holo.9.png b/core/res/res/drawable-hdpi/ab_bottom_transparent_light_holo.9.png
new file mode 100644
index 0000000..d8b5edc
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ab_bottom_transparent_light_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ab_solid_dark_holo.9.png b/core/res/res/drawable-hdpi/ab_solid_dark_holo.9.png
new file mode 100644
index 0000000..660a234
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ab_solid_dark_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ab_solid_light_holo.9.png b/core/res/res/drawable-hdpi/ab_solid_light_holo.9.png
new file mode 100644
index 0000000..9756cf5
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ab_solid_light_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ab_solid_shadow_holo.9.png b/core/res/res/drawable-hdpi/ab_solid_shadow_holo.9.png
new file mode 100644
index 0000000..80213d5
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ab_solid_shadow_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ab_stacked_solid_dark_holo.9.png b/core/res/res/drawable-hdpi/ab_stacked_solid_dark_holo.9.png
new file mode 100644
index 0000000..6de2bf2
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ab_stacked_solid_dark_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ab_stacked_solid_inverse_holo.9.png b/core/res/res/drawable-hdpi/ab_stacked_solid_inverse_holo.9.png
new file mode 100644
index 0000000..c23e473
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ab_stacked_solid_inverse_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ab_stacked_solid_light_holo.9.png b/core/res/res/drawable-hdpi/ab_stacked_solid_light_holo.9.png
new file mode 100644
index 0000000..343d7c6
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ab_stacked_solid_light_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ab_stacked_transparent_dark_holo.9.png b/core/res/res/drawable-hdpi/ab_stacked_transparent_dark_holo.9.png
new file mode 100644
index 0000000..3de1174
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ab_stacked_transparent_dark_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ab_stacked_transparent_light_holo.9.png b/core/res/res/drawable-hdpi/ab_stacked_transparent_light_holo.9.png
new file mode 100644
index 0000000..da8b042
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ab_stacked_transparent_light_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ab_transparent_dark_holo.9.png b/core/res/res/drawable-hdpi/ab_transparent_dark_holo.9.png
new file mode 100644
index 0000000..1957c32
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ab_transparent_dark_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ab_transparent_light_holo.9.png b/core/res/res/drawable-hdpi/ab_transparent_light_holo.9.png
new file mode 100644
index 0000000..0f1ce73
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ab_transparent_light_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_ab_back_holo_dark.png b/core/res/res/drawable-hdpi/ic_ab_back_holo_dark.png
index 7855cda..897a1c1 100644
--- a/core/res/res/drawable-hdpi/ic_ab_back_holo_dark.png
+++ b/core/res/res/drawable-hdpi/ic_ab_back_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_ab_back_holo_light.png b/core/res/res/drawable-hdpi/ic_ab_back_holo_light.png
index c062773..0c89f71 100644
--- a/core/res/res/drawable-hdpi/ic_ab_back_holo_light.png
+++ b/core/res/res/drawable-hdpi/ic_ab_back_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_menu_copy.png b/core/res/res/drawable-hdpi/ic_menu_copy.png
new file mode 100644
index 0000000..5dcc3a3
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_menu_copy.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_menu_copy_holo_dark.png b/core/res/res/drawable-hdpi/ic_menu_copy_holo_dark.png
index 852f146..d1e1337 100644
--- a/core/res/res/drawable-hdpi/ic_menu_copy_holo_dark.png
+++ b/core/res/res/drawable-hdpi/ic_menu_copy_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_menu_copy_holo_light.png b/core/res/res/drawable-hdpi/ic_menu_copy_holo_light.png
index ad09b37..5d02660 100644
--- a/core/res/res/drawable-hdpi/ic_menu_copy_holo_light.png
+++ b/core/res/res/drawable-hdpi/ic_menu_copy_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_menu_cut.png b/core/res/res/drawable-hdpi/ic_menu_cut.png
new file mode 100644
index 0000000..03fac98
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_menu_cut.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_menu_cut_holo_dark.png b/core/res/res/drawable-hdpi/ic_menu_cut_holo_dark.png
index 7716a94..bd28a85 100644
--- a/core/res/res/drawable-hdpi/ic_menu_cut_holo_dark.png
+++ b/core/res/res/drawable-hdpi/ic_menu_cut_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_menu_cut_holo_light.png b/core/res/res/drawable-hdpi/ic_menu_cut_holo_light.png
index bea6db1..037c362 100644
--- a/core/res/res/drawable-hdpi/ic_menu_cut_holo_light.png
+++ b/core/res/res/drawable-hdpi/ic_menu_cut_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_menu_find_holo_dark.png b/core/res/res/drawable-hdpi/ic_menu_find_holo_dark.png
index b888202..b981a4d 100644
--- a/core/res/res/drawable-hdpi/ic_menu_find_holo_dark.png
+++ b/core/res/res/drawable-hdpi/ic_menu_find_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_menu_find_holo_light.png b/core/res/res/drawable-hdpi/ic_menu_find_holo_light.png
index b888202..efee6df 100644
--- a/core/res/res/drawable-hdpi/ic_menu_find_holo_light.png
+++ b/core/res/res/drawable-hdpi/ic_menu_find_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_menu_moreoverflow.png b/core/res/res/drawable-hdpi/ic_menu_moreoverflow.png
new file mode 100644
index 0000000..33bb5e76
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_menu_moreoverflow.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_menu_moreoverflow_normal_holo_dark.png b/core/res/res/drawable-hdpi/ic_menu_moreoverflow_normal_holo_dark.png
index 8563c1a..1e69eac 100644
--- a/core/res/res/drawable-hdpi/ic_menu_moreoverflow_normal_holo_dark.png
+++ b/core/res/res/drawable-hdpi/ic_menu_moreoverflow_normal_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_menu_moreoverflow_normal_holo_light.png b/core/res/res/drawable-hdpi/ic_menu_moreoverflow_normal_holo_light.png
index 1cd2384..2f6accc 100644
--- a/core/res/res/drawable-hdpi/ic_menu_moreoverflow_normal_holo_light.png
+++ b/core/res/res/drawable-hdpi/ic_menu_moreoverflow_normal_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_menu_paste.png b/core/res/res/drawable-hdpi/ic_menu_paste.png
new file mode 100644
index 0000000..c24fd86
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_menu_paste.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_menu_paste_holo_dark.png b/core/res/res/drawable-hdpi/ic_menu_paste_holo_dark.png
index 5579443..e9514b8 100644
--- a/core/res/res/drawable-hdpi/ic_menu_paste_holo_dark.png
+++ b/core/res/res/drawable-hdpi/ic_menu_paste_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_menu_paste_holo_light.png b/core/res/res/drawable-hdpi/ic_menu_paste_holo_light.png
index 6674914..b02aa09 100644
--- a/core/res/res/drawable-hdpi/ic_menu_paste_holo_light.png
+++ b/core/res/res/drawable-hdpi/ic_menu_paste_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_menu_share_holo_dark.png b/core/res/res/drawable-hdpi/ic_menu_share_holo_dark.png
index 2837615..db011be 100644
--- a/core/res/res/drawable-hdpi/ic_menu_share_holo_dark.png
+++ b/core/res/res/drawable-hdpi/ic_menu_share_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_menu_share_holo_light.png b/core/res/res/drawable-hdpi/ic_menu_share_holo_light.png
index 2837615..d9a9a73 100644
--- a/core/res/res/drawable-hdpi/ic_menu_share_holo_light.png
+++ b/core/res/res/drawable-hdpi/ic_menu_share_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ab_bottom_solid_dark_holo.9.png b/core/res/res/drawable-mdpi/ab_bottom_solid_dark_holo.9.png
new file mode 100644
index 0000000..3807a48
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ab_bottom_solid_dark_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ab_bottom_solid_inverse_holo.9.png b/core/res/res/drawable-mdpi/ab_bottom_solid_inverse_holo.9.png
new file mode 100644
index 0000000..9994438
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ab_bottom_solid_inverse_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ab_bottom_solid_light_holo.9.png b/core/res/res/drawable-mdpi/ab_bottom_solid_light_holo.9.png
new file mode 100644
index 0000000..5648403
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ab_bottom_solid_light_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ab_bottom_transparent_dark_holo.9.png b/core/res/res/drawable-mdpi/ab_bottom_transparent_dark_holo.9.png
new file mode 100644
index 0000000..261365d
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ab_bottom_transparent_dark_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ab_bottom_transparent_light_holo.9.png b/core/res/res/drawable-mdpi/ab_bottom_transparent_light_holo.9.png
new file mode 100644
index 0000000..95df5fc
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ab_bottom_transparent_light_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ab_solid_dark_holo.9.png b/core/res/res/drawable-mdpi/ab_solid_dark_holo.9.png
new file mode 100644
index 0000000..4a6c3bc
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ab_solid_dark_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ab_solid_light_holo.9.png b/core/res/res/drawable-mdpi/ab_solid_light_holo.9.png
new file mode 100644
index 0000000..93a0c3e
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ab_solid_light_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ab_solid_shadow_holo.9.png b/core/res/res/drawable-mdpi/ab_solid_shadow_holo.9.png
new file mode 100644
index 0000000..f3abd07
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ab_solid_shadow_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ab_stacked_solid_dark_holo.9.png b/core/res/res/drawable-mdpi/ab_stacked_solid_dark_holo.9.png
new file mode 100644
index 0000000..e1d8f67
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ab_stacked_solid_dark_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ab_stacked_solid_inverse_holo.9.png b/core/res/res/drawable-mdpi/ab_stacked_solid_inverse_holo.9.png
new file mode 100644
index 0000000..9d7e953
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ab_stacked_solid_inverse_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ab_stacked_solid_light_holo.9.png b/core/res/res/drawable-mdpi/ab_stacked_solid_light_holo.9.png
new file mode 100644
index 0000000..711e0fd
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ab_stacked_solid_light_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ab_stacked_transparent_dark_holo.9.png b/core/res/res/drawable-mdpi/ab_stacked_transparent_dark_holo.9.png
new file mode 100644
index 0000000..9649a2d
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ab_stacked_transparent_dark_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ab_stacked_transparent_light_holo.9.png b/core/res/res/drawable-mdpi/ab_stacked_transparent_light_holo.9.png
new file mode 100644
index 0000000..376e4ef
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ab_stacked_transparent_light_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ab_transparent_dark_holo.9.png b/core/res/res/drawable-mdpi/ab_transparent_dark_holo.9.png
new file mode 100644
index 0000000..99c8fd3
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ab_transparent_dark_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ab_transparent_light_holo.9.png b/core/res/res/drawable-mdpi/ab_transparent_light_holo.9.png
new file mode 100644
index 0000000..a86ec34
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ab_transparent_light_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_ab_back_holo_dark.png b/core/res/res/drawable-mdpi/ic_ab_back_holo_dark.png
index ae3e6bf..df2d3d1 100644
--- a/core/res/res/drawable-mdpi/ic_ab_back_holo_dark.png
+++ b/core/res/res/drawable-mdpi/ic_ab_back_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_ab_back_holo_light.png b/core/res/res/drawable-mdpi/ic_ab_back_holo_light.png
index c61e3fa..b2aa9c2 100644
--- a/core/res/res/drawable-mdpi/ic_ab_back_holo_light.png
+++ b/core/res/res/drawable-mdpi/ic_ab_back_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_menu_copy.png b/core/res/res/drawable-mdpi/ic_menu_copy.png
new file mode 100644
index 0000000..eee5540
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_menu_copy.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_menu_copy_holo_dark.png b/core/res/res/drawable-mdpi/ic_menu_copy_holo_dark.png
index 35c3318..cb19fea 100644
--- a/core/res/res/drawable-mdpi/ic_menu_copy_holo_dark.png
+++ b/core/res/res/drawable-mdpi/ic_menu_copy_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_menu_copy_holo_light.png b/core/res/res/drawable-mdpi/ic_menu_copy_holo_light.png
index 3b179d8..e353d46 100644
--- a/core/res/res/drawable-mdpi/ic_menu_copy_holo_light.png
+++ b/core/res/res/drawable-mdpi/ic_menu_copy_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_menu_cut.png b/core/res/res/drawable-mdpi/ic_menu_cut.png
new file mode 100644
index 0000000..865d1e0
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_menu_cut.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_menu_cut_holo_dark.png b/core/res/res/drawable-mdpi/ic_menu_cut_holo_dark.png
index dfe8b4a..66a750d 100644
--- a/core/res/res/drawable-mdpi/ic_menu_cut_holo_dark.png
+++ b/core/res/res/drawable-mdpi/ic_menu_cut_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_menu_cut_holo_light.png b/core/res/res/drawable-mdpi/ic_menu_cut_holo_light.png
index 748dc9b..e7e8c54 100644
--- a/core/res/res/drawable-mdpi/ic_menu_cut_holo_light.png
+++ b/core/res/res/drawable-mdpi/ic_menu_cut_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_menu_find_holo_dark.png b/core/res/res/drawable-mdpi/ic_menu_find_holo_dark.png
index 82dcba7..45f8fd3 100644
--- a/core/res/res/drawable-mdpi/ic_menu_find_holo_dark.png
+++ b/core/res/res/drawable-mdpi/ic_menu_find_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_menu_find_holo_light.png b/core/res/res/drawable-mdpi/ic_menu_find_holo_light.png
index 82dcba7..9033f1e 100644
--- a/core/res/res/drawable-mdpi/ic_menu_find_holo_light.png
+++ b/core/res/res/drawable-mdpi/ic_menu_find_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_menu_moreoverflow.png b/core/res/res/drawable-mdpi/ic_menu_moreoverflow.png
new file mode 100644
index 0000000..e478922
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_menu_moreoverflow.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_menu_moreoverflow_focused_holo_dark.png b/core/res/res/drawable-mdpi/ic_menu_moreoverflow_focused_holo_dark.png
index c369e6f..48d6c78 100644
--- a/core/res/res/drawable-mdpi/ic_menu_moreoverflow_focused_holo_dark.png
+++ b/core/res/res/drawable-mdpi/ic_menu_moreoverflow_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_menu_moreoverflow_focused_holo_light.png b/core/res/res/drawable-mdpi/ic_menu_moreoverflow_focused_holo_light.png
index a4df2bf..50ff8fc 100644
--- a/core/res/res/drawable-mdpi/ic_menu_moreoverflow_focused_holo_light.png
+++ b/core/res/res/drawable-mdpi/ic_menu_moreoverflow_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_menu_moreoverflow_normal_holo_dark.png b/core/res/res/drawable-mdpi/ic_menu_moreoverflow_normal_holo_dark.png
index a7389c9..135ca6e 100644
--- a/core/res/res/drawable-mdpi/ic_menu_moreoverflow_normal_holo_dark.png
+++ b/core/res/res/drawable-mdpi/ic_menu_moreoverflow_normal_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_menu_moreoverflow_normal_holo_light.png b/core/res/res/drawable-mdpi/ic_menu_moreoverflow_normal_holo_light.png
index 87e41ac..ccbf143 100644
--- a/core/res/res/drawable-mdpi/ic_menu_moreoverflow_normal_holo_light.png
+++ b/core/res/res/drawable-mdpi/ic_menu_moreoverflow_normal_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_menu_paste.png b/core/res/res/drawable-mdpi/ic_menu_paste.png
new file mode 100644
index 0000000..8c9916c
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_menu_paste.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_menu_paste_holo_dark.png b/core/res/res/drawable-mdpi/ic_menu_paste_holo_dark.png
index caec299..23f3a32 100644
--- a/core/res/res/drawable-mdpi/ic_menu_paste_holo_dark.png
+++ b/core/res/res/drawable-mdpi/ic_menu_paste_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_menu_paste_holo_light.png b/core/res/res/drawable-mdpi/ic_menu_paste_holo_light.png
index 434f5d1..c9d571c 100644
--- a/core/res/res/drawable-mdpi/ic_menu_paste_holo_light.png
+++ b/core/res/res/drawable-mdpi/ic_menu_paste_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_menu_share_holo_dark.png b/core/res/res/drawable-mdpi/ic_menu_share_holo_dark.png
index d89ca5f..306cac8 100755..100644
--- a/core/res/res/drawable-mdpi/ic_menu_share_holo_dark.png
+++ b/core/res/res/drawable-mdpi/ic_menu_share_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_menu_share_holo_light.png b/core/res/res/drawable-mdpi/ic_menu_share_holo_light.png
index d89ca5f..cc081ad 100755..100644
--- a/core/res/res/drawable-mdpi/ic_menu_share_holo_light.png
+++ b/core/res/res/drawable-mdpi/ic_menu_share_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ab_bottom_solid_dark_holo.9.png b/core/res/res/drawable-xhdpi/ab_bottom_solid_dark_holo.9.png
new file mode 100644
index 0000000..462e0e0
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ab_bottom_solid_dark_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ab_bottom_solid_inverse_holo.9.png b/core/res/res/drawable-xhdpi/ab_bottom_solid_inverse_holo.9.png
new file mode 100644
index 0000000..939ff4e
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ab_bottom_solid_inverse_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ab_bottom_solid_light_holo.9.png b/core/res/res/drawable-xhdpi/ab_bottom_solid_light_holo.9.png
new file mode 100644
index 0000000..8f89040
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ab_bottom_solid_light_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ab_bottom_transparent_dark_holo.9.png b/core/res/res/drawable-xhdpi/ab_bottom_transparent_dark_holo.9.png
new file mode 100644
index 0000000..ccd53a3
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ab_bottom_transparent_dark_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ab_bottom_transparent_light_holo.9.png b/core/res/res/drawable-xhdpi/ab_bottom_transparent_light_holo.9.png
new file mode 100644
index 0000000..0b1ae2d
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ab_bottom_transparent_light_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ab_solid_dark_holo.9.png b/core/res/res/drawable-xhdpi/ab_solid_dark_holo.9.png
new file mode 100644
index 0000000..c8e5efc4
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ab_solid_dark_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ab_solid_light_holo.9.png b/core/res/res/drawable-xhdpi/ab_solid_light_holo.9.png
new file mode 100644
index 0000000..6cb8a0e
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ab_solid_light_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ab_solid_shadow_holo.9.png b/core/res/res/drawable-xhdpi/ab_solid_shadow_holo.9.png
new file mode 100644
index 0000000..49b2669
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ab_solid_shadow_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ab_stacked_solid_dark_holo.9.png b/core/res/res/drawable-xhdpi/ab_stacked_solid_dark_holo.9.png
new file mode 100644
index 0000000..201e21d
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ab_stacked_solid_dark_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ab_stacked_solid_inverse_holo.9.png b/core/res/res/drawable-xhdpi/ab_stacked_solid_inverse_holo.9.png
new file mode 100644
index 0000000..ac96200
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ab_stacked_solid_inverse_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ab_stacked_solid_light_holo.9.png b/core/res/res/drawable-xhdpi/ab_stacked_solid_light_holo.9.png
new file mode 100644
index 0000000..d605d96
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ab_stacked_solid_light_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ab_stacked_transparent_dark_holo.9.png b/core/res/res/drawable-xhdpi/ab_stacked_transparent_dark_holo.9.png
new file mode 100644
index 0000000..8ece2a9
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ab_stacked_transparent_dark_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ab_stacked_transparent_light_holo.9.png b/core/res/res/drawable-xhdpi/ab_stacked_transparent_light_holo.9.png
new file mode 100644
index 0000000..ae0b6b7
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ab_stacked_transparent_light_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ab_transparent_dark_holo.9.png b/core/res/res/drawable-xhdpi/ab_transparent_dark_holo.9.png
new file mode 100644
index 0000000..d3a3809
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ab_transparent_dark_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ab_transparent_light_holo.9.png b/core/res/res/drawable-xhdpi/ab_transparent_light_holo.9.png
new file mode 100644
index 0000000..7e6e24d
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ab_transparent_light_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_ab_back_holo_dark.png b/core/res/res/drawable-xhdpi/ic_ab_back_holo_dark.png
new file mode 100644
index 0000000..8ded62f
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_ab_back_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_ab_back_holo_light.png b/core/res/res/drawable-xhdpi/ic_ab_back_holo_light.png
new file mode 100644
index 0000000..517e9f7
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_ab_back_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_account_list.png b/core/res/res/drawable-xhdpi/ic_menu_account_list.png
new file mode 100644
index 0000000..ebe29b9
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_account_list.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_add.png b/core/res/res/drawable-xhdpi/ic_menu_add.png
new file mode 100644
index 0000000..7d498a9
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_add.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_agenda.png b/core/res/res/drawable-xhdpi/ic_menu_agenda.png
new file mode 100644
index 0000000..25e9f11
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_agenda.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_allfriends.png b/core/res/res/drawable-xhdpi/ic_menu_allfriends.png
new file mode 100644
index 0000000..20994ed
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_allfriends.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_always_landscape_portrait.png b/core/res/res/drawable-xhdpi/ic_menu_always_landscape_portrait.png
new file mode 100644
index 0000000..96606de
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_always_landscape_portrait.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_archive.png b/core/res/res/drawable-xhdpi/ic_menu_archive.png
new file mode 100644
index 0000000..b1be9d5
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_archive.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_attachment.png b/core/res/res/drawable-xhdpi/ic_menu_attachment.png
new file mode 100644
index 0000000..aa41bd6
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_attachment.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_back.png b/core/res/res/drawable-xhdpi/ic_menu_back.png
new file mode 100644
index 0000000..8ac4f64
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_back.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_block.png b/core/res/res/drawable-xhdpi/ic_menu_block.png
new file mode 100644
index 0000000..e672395
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_block.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_blocked_user.png b/core/res/res/drawable-xhdpi/ic_menu_blocked_user.png
new file mode 100644
index 0000000..53a279e
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_blocked_user.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_btn_add.png b/core/res/res/drawable-xhdpi/ic_menu_btn_add.png
new file mode 100644
index 0000000..7d498a9
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_btn_add.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_call.png b/core/res/res/drawable-xhdpi/ic_menu_call.png
new file mode 100644
index 0000000..703a76b
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_call.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_camera.png b/core/res/res/drawable-xhdpi/ic_menu_camera.png
new file mode 100644
index 0000000..7875aa3
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_camera.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_cc.png b/core/res/res/drawable-xhdpi/ic_menu_cc.png
new file mode 100644
index 0000000..50d686a
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_cc.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_chat_dashboard.png b/core/res/res/drawable-xhdpi/ic_menu_chat_dashboard.png
new file mode 100644
index 0000000..c0b238c
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_chat_dashboard.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_clear_playlist.png b/core/res/res/drawable-xhdpi/ic_menu_clear_playlist.png
new file mode 100644
index 0000000..8981d6f
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_clear_playlist.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_close_clear_cancel.png b/core/res/res/drawable-xhdpi/ic_menu_close_clear_cancel.png
new file mode 100644
index 0000000..d743d75
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_close_clear_cancel.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_compass.png b/core/res/res/drawable-xhdpi/ic_menu_compass.png
new file mode 100644
index 0000000..1c2ad89
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_compass.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_compose.png b/core/res/res/drawable-xhdpi/ic_menu_compose.png
new file mode 100644
index 0000000..bef190e
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_compose.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_copy.png b/core/res/res/drawable-xhdpi/ic_menu_copy.png
new file mode 100644
index 0000000..22761fc
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_copy.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_copy_holo_dark.png b/core/res/res/drawable-xhdpi/ic_menu_copy_holo_dark.png
new file mode 100644
index 0000000..8014345
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_copy_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_copy_holo_light.png b/core/res/res/drawable-xhdpi/ic_menu_copy_holo_light.png
new file mode 100644
index 0000000..b5359a1
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_copy_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_crop.png b/core/res/res/drawable-xhdpi/ic_menu_crop.png
new file mode 100644
index 0000000..d32daae
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_crop.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_cut.png b/core/res/res/drawable-xhdpi/ic_menu_cut.png
new file mode 100644
index 0000000..efefcde
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_cut.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_cut_holo_dark.png b/core/res/res/drawable-xhdpi/ic_menu_cut_holo_dark.png
new file mode 100644
index 0000000..180365f
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_cut_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_cut_holo_light.png b/core/res/res/drawable-xhdpi/ic_menu_cut_holo_light.png
new file mode 100644
index 0000000..a31a06f
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_cut_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_day.png b/core/res/res/drawable-xhdpi/ic_menu_day.png
new file mode 100644
index 0000000..9eed1b2
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_day.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_delete.png b/core/res/res/drawable-xhdpi/ic_menu_delete.png
new file mode 100644
index 0000000..65b9cae
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_delete.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_directions.png b/core/res/res/drawable-xhdpi/ic_menu_directions.png
new file mode 100644
index 0000000..bdc0088
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_directions.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_edit.png b/core/res/res/drawable-xhdpi/ic_menu_edit.png
new file mode 100644
index 0000000..fcdd71e
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_edit.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_emoticons.png b/core/res/res/drawable-xhdpi/ic_menu_emoticons.png
new file mode 100644
index 0000000..af730fa
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_emoticons.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_end_conversation.png b/core/res/res/drawable-xhdpi/ic_menu_end_conversation.png
new file mode 100644
index 0000000..ac76f3b
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_end_conversation.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_find.png b/core/res/res/drawable-xhdpi/ic_menu_find.png
new file mode 100644
index 0000000..ccf2aab
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_find.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_find_holo_dark.png b/core/res/res/drawable-xhdpi/ic_menu_find_holo_dark.png
new file mode 100644
index 0000000..3ede9e2
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_find_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_find_holo_light.png b/core/res/res/drawable-xhdpi/ic_menu_find_holo_light.png
new file mode 100644
index 0000000..de20fa0
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_find_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_forward.png b/core/res/res/drawable-xhdpi/ic_menu_forward.png
new file mode 100644
index 0000000..6463e7a
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_forward.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_friendslist.png b/core/res/res/drawable-xhdpi/ic_menu_friendslist.png
new file mode 100644
index 0000000..9200f87
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_friendslist.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_gallery.png b/core/res/res/drawable-xhdpi/ic_menu_gallery.png
new file mode 100644
index 0000000..6b21e22
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_gallery.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_goto.png b/core/res/res/drawable-xhdpi/ic_menu_goto.png
new file mode 100644
index 0000000..b925e69
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_goto.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_help.png b/core/res/res/drawable-xhdpi/ic_menu_help.png
new file mode 100644
index 0000000..128c7e8
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_help.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_help_holo_light.png b/core/res/res/drawable-xhdpi/ic_menu_help_holo_light.png
new file mode 100644
index 0000000..b961de9
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_help_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_home.png b/core/res/res/drawable-xhdpi/ic_menu_home.png
new file mode 100644
index 0000000..689f372
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_home.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_info_details.png b/core/res/res/drawable-xhdpi/ic_menu_info_details.png
new file mode 100644
index 0000000..24ea543
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_info_details.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_invite.png b/core/res/res/drawable-xhdpi/ic_menu_invite.png
new file mode 100644
index 0000000..d594607
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_invite.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_login.png b/core/res/res/drawable-xhdpi/ic_menu_login.png
new file mode 100644
index 0000000..5095ed9
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_login.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_manage.png b/core/res/res/drawable-xhdpi/ic_menu_manage.png
new file mode 100644
index 0000000..d743624
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_manage.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_mapmode.png b/core/res/res/drawable-xhdpi/ic_menu_mapmode.png
new file mode 100644
index 0000000..0b62d08
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_mapmode.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_mark.png b/core/res/res/drawable-xhdpi/ic_menu_mark.png
new file mode 100644
index 0000000..a5de6fb
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_mark.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_month.png b/core/res/res/drawable-xhdpi/ic_menu_month.png
new file mode 100644
index 0000000..099263b
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_month.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_more.png b/core/res/res/drawable-xhdpi/ic_menu_more.png
new file mode 100644
index 0000000..c7a6538
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_more.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_moreoverflow.png b/core/res/res/drawable-xhdpi/ic_menu_moreoverflow.png
new file mode 100644
index 0000000..2998d65
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_moreoverflow.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_moreoverflow_focused_holo_dark.png b/core/res/res/drawable-xhdpi/ic_menu_moreoverflow_focused_holo_dark.png
new file mode 100644
index 0000000..62659fa
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_moreoverflow_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_moreoverflow_focused_holo_light.png b/core/res/res/drawable-xhdpi/ic_menu_moreoverflow_focused_holo_light.png
new file mode 100644
index 0000000..341edaf
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_moreoverflow_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_moreoverflow_normal_holo_dark.png b/core/res/res/drawable-xhdpi/ic_menu_moreoverflow_normal_holo_dark.png
new file mode 100644
index 0000000..81306ca
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_moreoverflow_normal_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_moreoverflow_normal_holo_light.png b/core/res/res/drawable-xhdpi/ic_menu_moreoverflow_normal_holo_light.png
new file mode 100644
index 0000000..1f46e7a
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_moreoverflow_normal_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_my_calendar.png b/core/res/res/drawable-xhdpi/ic_menu_my_calendar.png
new file mode 100644
index 0000000..ca95b92
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_my_calendar.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_mylocation.png b/core/res/res/drawable-xhdpi/ic_menu_mylocation.png
new file mode 100644
index 0000000..b0a76a2
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_mylocation.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_myplaces.png b/core/res/res/drawable-xhdpi/ic_menu_myplaces.png
new file mode 100644
index 0000000..205848e
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_myplaces.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_notifications.png b/core/res/res/drawable-xhdpi/ic_menu_notifications.png
new file mode 100644
index 0000000..db80b57
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_notifications.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_paste.png b/core/res/res/drawable-xhdpi/ic_menu_paste.png
new file mode 100644
index 0000000..a69f0eb
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_paste.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_paste_holo_dark.png b/core/res/res/drawable-xhdpi/ic_menu_paste_holo_dark.png
new file mode 100644
index 0000000..6e7273f
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_paste_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_paste_holo_light.png b/core/res/res/drawable-xhdpi/ic_menu_paste_holo_light.png
new file mode 100644
index 0000000..b7eedd9
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_paste_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_play_clip.png b/core/res/res/drawable-xhdpi/ic_menu_play_clip.png
new file mode 100644
index 0000000..f680fce
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_play_clip.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_preferences.png b/core/res/res/drawable-xhdpi/ic_menu_preferences.png
new file mode 100644
index 0000000..02cfbad
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_preferences.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_recent_history.png b/core/res/res/drawable-xhdpi/ic_menu_recent_history.png
new file mode 100644
index 0000000..fc5e1fc
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_recent_history.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_refresh.png b/core/res/res/drawable-xhdpi/ic_menu_refresh.png
new file mode 100644
index 0000000..9e9f10e
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_refresh.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_report_image.png b/core/res/res/drawable-xhdpi/ic_menu_report_image.png
new file mode 100644
index 0000000..26f7ff4
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_report_image.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_revert.png b/core/res/res/drawable-xhdpi/ic_menu_revert.png
new file mode 100644
index 0000000..19c580f
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_revert.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_rotate.png b/core/res/res/drawable-xhdpi/ic_menu_rotate.png
new file mode 100644
index 0000000..98e19fe
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_rotate.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_save.png b/core/res/res/drawable-xhdpi/ic_menu_save.png
new file mode 100644
index 0000000..62a66d8
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_save.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_search.png b/core/res/res/drawable-xhdpi/ic_menu_search.png
new file mode 100644
index 0000000..5c18f9e
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_search.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_search_holo_dark.png b/core/res/res/drawable-xhdpi/ic_menu_search_holo_dark.png
new file mode 100644
index 0000000..d49c7e2
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_search_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_search_holo_light.png b/core/res/res/drawable-xhdpi/ic_menu_search_holo_light.png
new file mode 100644
index 0000000..578cb24
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_search_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_selectall_holo_dark.png b/core/res/res/drawable-xhdpi/ic_menu_selectall_holo_dark.png
new file mode 100644
index 0000000..7125557
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_selectall_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_selectall_holo_light.png b/core/res/res/drawable-xhdpi/ic_menu_selectall_holo_light.png
new file mode 100644
index 0000000..c7728d4
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_selectall_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_send.png b/core/res/res/drawable-xhdpi/ic_menu_send.png
new file mode 100644
index 0000000..6e5ec78
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_send.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_set_as.png b/core/res/res/drawable-xhdpi/ic_menu_set_as.png
new file mode 100644
index 0000000..8689766
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_set_as.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_settings_holo_light.png b/core/res/res/drawable-xhdpi/ic_menu_settings_holo_light.png
new file mode 100644
index 0000000..aa33c38
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_settings_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_share.png b/core/res/res/drawable-xhdpi/ic_menu_share.png
new file mode 100644
index 0000000..fce1d35
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_share.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_share_holo_dark.png b/core/res/res/drawable-xhdpi/ic_menu_share_holo_dark.png
new file mode 100644
index 0000000..af72732
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_share_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_share_holo_light.png b/core/res/res/drawable-xhdpi/ic_menu_share_holo_light.png
new file mode 100644
index 0000000..79c162f
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_share_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_slideshow.png b/core/res/res/drawable-xhdpi/ic_menu_slideshow.png
new file mode 100644
index 0000000..8740f37
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_slideshow.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_sort_alphabetically.png b/core/res/res/drawable-xhdpi/ic_menu_sort_alphabetically.png
new file mode 100644
index 0000000..5736ff8
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_sort_alphabetically.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_sort_by_size.png b/core/res/res/drawable-xhdpi/ic_menu_sort_by_size.png
new file mode 100644
index 0000000..fe3836c
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_sort_by_size.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_star.png b/core/res/res/drawable-xhdpi/ic_menu_star.png
new file mode 100644
index 0000000..c051020
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_star.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_start_conversation.png b/core/res/res/drawable-xhdpi/ic_menu_start_conversation.png
new file mode 100644
index 0000000..d71ed17
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_start_conversation.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_stop.png b/core/res/res/drawable-xhdpi/ic_menu_stop.png
new file mode 100644
index 0000000..855af11
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_stop.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_today.png b/core/res/res/drawable-xhdpi/ic_menu_today.png
new file mode 100644
index 0000000..e9ebc5e
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_today.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_upload.png b/core/res/res/drawable-xhdpi/ic_menu_upload.png
new file mode 100644
index 0000000..94d1478
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_upload.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_upload_you_tube.png b/core/res/res/drawable-xhdpi/ic_menu_upload_you_tube.png
new file mode 100644
index 0000000..508c354
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_upload_you_tube.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_view.png b/core/res/res/drawable-xhdpi/ic_menu_view.png
new file mode 100644
index 0000000..e97c30df
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_view.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_week.png b/core/res/res/drawable-xhdpi/ic_menu_week.png
new file mode 100644
index 0000000..2c3e761
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_week.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_zoom.png b/core/res/res/drawable-xhdpi/ic_menu_zoom.png
new file mode 100644
index 0000000..858aef5
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_zoom.png
Binary files differ
diff --git a/core/res/res/layout-land/ssl_certificate.xml b/core/res/res/layout-land/ssl_certificate.xml
index c3e6deb..4f8bd8e 100644
--- a/core/res/res/layout-land/ssl_certificate.xml
+++ b/core/res/res/layout-land/ssl_certificate.xml
@@ -23,6 +23,7 @@
android:id="@+id/body"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:gravity="left"
android:orientation="vertical" >
<!-- Placeholder for the success message or one or more warnings -->
@@ -43,8 +44,7 @@
android:layout_weight="1"
android:gravity="fill_horizontal"
android:layout_marginLeft="20dip"
- android:layout_marginRight="20dip"
- android:layout_marginBottom="12dip" />
+ android:layout_marginRight="20dip"/>
<TableLayout
android:layout_width="match_parent"
@@ -58,7 +58,8 @@
android:text="@string/issued_to"
android:textStyle="bold"
android:layout_height="wrap_content"
- android:layout_width="wrap_content"
+ android:layout_width="match_parent"
+ android:layout_marginTop="12dip"
android:layout_marginLeft="20dip"
android:layout_marginRight="20dip"
android:layout_marginBottom="7dip" />
@@ -68,12 +69,10 @@
<TextView
android:id="@+id/to_common_header"
android:text="@string/common_name"
- android:gravity="left"
android:layout_marginLeft="20dip" />
<TextView
android:id="@+id/to_common"
- android:gravity="left"
android:layout_marginLeft="10dip"
android:layout_marginRight="20dip"
android:layout_marginBottom="7dip" />
@@ -84,12 +83,10 @@
<TextView
android:id="@+id/to_org_header"
android:text="@string/org_name"
- android:gravity="left"
android:layout_marginLeft="20dip" />
<TextView
android:id="@+id/to_org"
- android:gravity="left"
android:layout_marginLeft="10dip"
android:layout_marginRight="20dip"
android:layout_marginBottom="7dip" />
@@ -100,15 +97,27 @@
<TextView
android:id="@+id/to_org_unit_header"
android:text="@string/org_unit"
- android:gravity="left"
android:layout_marginLeft="20dip" />
<TextView
android:id="@+id/to_org_unit"
- android:gravity="left"
android:layout_marginLeft="10dip"
android:layout_marginRight="20dip"
- android:layout_marginBottom="12dip" />
+ android:layout_marginBottom="7dip" />
+ </TableRow>
+
+ <!-- Serial number: -->
+ <TableRow>
+ <TextView
+ android:id="@+id/serial_number_header"
+ android:text="@string/serial_number"
+ android:layout_marginLeft="20dip" />
+
+ <TextView
+ android:id="@+id/serial_number"
+ android:layout_marginLeft="10dip"
+ android:layout_marginRight="20dip"
+ android:layout_marginBottom="7dip" />
</TableRow>
<!-- Issued by: -->
@@ -117,7 +126,8 @@
android:text="@string/issued_by"
android:textStyle="bold"
android:layout_height="wrap_content"
- android:layout_width="wrap_content"
+ android:layout_width="match_parent"
+ android:layout_marginTop="12dip"
android:layout_marginLeft="20dip"
android:layout_marginRight="20dip"
android:layout_marginBottom="7dip" />
@@ -127,12 +137,10 @@
<TextView
android:id="@+id/by_common_header"
android:text="@string/common_name"
- android:gravity="left"
android:layout_marginLeft="20dip" />
<TextView
android:id="@+id/by_common"
- android:gravity="left"
android:layout_marginLeft="10dip"
android:layout_marginRight="20dip"
android:layout_marginBottom="7dip" />
@@ -143,12 +151,10 @@
<TextView
android:id="@+id/by_org_header"
android:text="@string/org_name"
- android:gravity="left"
android:layout_marginLeft="20dip" />
<TextView
android:id="@+id/by_org"
- android:gravity="left"
android:layout_marginLeft="10dip"
android:layout_marginRight="20dip"
android:layout_marginBottom="7dip" />
@@ -159,24 +165,23 @@
<TextView
android:id="@+id/by_org_unit_header"
android:text="@string/org_unit"
- android:gravity="left"
android:layout_marginLeft="20dip" />
<TextView
android:id="@+id/by_org_unit"
- android:gravity="left"
android:layout_marginLeft="10dip"
android:layout_marginRight="20dip"
- android:layout_marginBottom="12dip" />
+ android:layout_marginBottom="7dip" />
</TableRow>
<!-- Validity Dates: -->
<TextView
android:id="@+id/validity_header"
android:layout_height="wrap_content"
- android:layout_width="wrap_content"
+ android:layout_width="match_parent"
android:text="@string/validity_period"
android:textStyle="bold"
+ android:layout_marginTop="12dip"
android:layout_marginLeft="20dip"
android:layout_marginRight="20dip"
android:layout_marginBottom="7dip" />
@@ -185,17 +190,15 @@
<TableRow>
<TextView
android:id="@+id/issued_on_header"
- android:layout_width="wrap_content"
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/issued_on"
- android:gravity="left"
android:layout_marginLeft="20dip" />
<TextView
android:id="@+id/issued_on"
android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:gravity="left"
+ android:layout_width="match_parent"
android:layout_marginLeft="10dip"
android:layout_marginRight="20dip"
android:layout_marginBottom="7dip" />
@@ -206,20 +209,68 @@
<TableRow>
<TextView
android:id="@+id/expires_on_header"
- android:layout_width="wrap_content"
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/expires_on"
- android:gravity="left"
android:layout_marginLeft="20dip" />
<TextView
android:id="@+id/expires_on"
android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:gravity="left"
+ android:layout_width="match_parent"
+ android:layout_marginLeft="10dip"
+ android:layout_marginRight="20dip"
+ android:layout_marginBottom="7dip" />
+ </TableRow>
+
+ <!-- Fingerprints: -->
+ <TextView
+ android:id="@+id/fingerprints"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:text="@string/fingerprints"
+ android:textStyle="bold"
+ android:layout_marginTop="12dip"
+ android:layout_marginLeft="20dip"
+ android:layout_marginRight="20dip"
+ android:layout_marginBottom="7dip" />
+
+ <!-- SHA-256 fingerprint: -->
+ <TableRow>
+ <TextView
+ android:id="@+id/sha256_fingerprint_header"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/sha256_fingerprint"
+ android:layout_marginLeft="20dip" />
+
+ <TextView
+ android:id="@+id/sha256_fingerprint"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
android:layout_marginLeft="10dip"
android:layout_marginRight="20dip"
- android:layout_marginBottom="12dip" />
+ android:layout_marginBottom="7dip" />
+
+ </TableRow>
+
+ <!-- SHA-1 fingerprint: -->
+ <TableRow>
+ <TextView
+ android:id="@+id/sha1_fingerprint_header"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/sha1_fingerprint"
+ android:layout_marginLeft="20dip" />
+
+ <TextView
+ android:id="@+id/sha1_fingerprint"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:layout_marginLeft="10dip"
+ android:layout_marginRight="20dip"
+ android:layout_marginBottom="7dip" />
+
</TableRow>
</TableLayout>
diff --git a/core/res/res/layout/action_menu_item_layout.xml b/core/res/res/layout/action_menu_item_layout.xml
index a8f0c22..dca6c52 100644
--- a/core/res/res/layout/action_menu_item_layout.xml
+++ b/core/res/res/layout/action_menu_item_layout.xml
@@ -21,8 +21,8 @@
android:addStatesFromChildren="true"
android:gravity="center"
android:focusable="true"
- android:paddingLeft="12dip"
- android:paddingRight="12dip"
+ android:paddingLeft="4dip"
+ android:paddingRight="4dip"
style="?android:attr/actionButtonStyle">
<ImageButton android:id="@+id/imageButton"
android:layout_width="wrap_content"
@@ -45,6 +45,8 @@
android:textAppearance="?attr/actionMenuTextAppearance"
style="?attr/buttonStyleSmall"
android:textColor="?attr/actionMenuTextColor"
+ android:singleLine="true"
+ android:ellipsize="none"
android:background="@null"
android:paddingTop="4dip"
android:paddingBottom="4dip"
diff --git a/core/res/res/layout/ssl_certificate.xml b/core/res/res/layout/ssl_certificate.xml
index ae661ce..dd89a2d 100644
--- a/core/res/res/layout/ssl_certificate.xml
+++ b/core/res/res/layout/ssl_certificate.xml
@@ -23,6 +23,7 @@
android:id="@+id/body"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:gravity="left"
android:orientation="vertical" >
<!-- Placeholder for the success message or one or more warnings -->
@@ -43,200 +44,242 @@
android:layout_weight="1"
android:gravity="fill_horizontal"
android:layout_marginRight="20dip"
+ android:layout_marginLeft="20dip"/>
+
+ <!-- Issued to: -->
+ <TextView
+ android:id="@+id/issued_to_header"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:text="@string/issued_to"
+ android:textStyle="bold"
+ android:layout_marginTop="12dip"
+ android:layout_marginLeft="20dip"
+ android:layout_marginRight="20dip"
+ android:layout_marginBottom="7dip" />
+
+ <!-- Common name: -->
+ <TextView
+ android:id="@+id/to_common_header"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:text="@string/common_name"
+ android:layout_marginLeft="20dip"
+ android:layout_marginRight="20dip" />
+
+ <TextView
+ android:id="@+id/to_common"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:layout_marginLeft="20dip"
+ android:layout_marginRight="20dip"
+ android:layout_marginBottom="7dip" />
+
+ <!-- Organization: -->
+ <TextView
+ android:id="@+id/to_org_header"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:text="@string/org_name"
+ android:layout_marginLeft="20dip"
+ android:layout_marginRight="20dip" />
+
+ <TextView
+ android:id="@+id/to_org"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:layout_marginLeft="20dip"
+ android:layout_marginRight="20dip"
+ android:layout_marginBottom="7dip" />
+
+ <!-- Organizational unit: -->
+ <TextView
+ android:id="@+id/to_org_unit_header"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:text="@string/org_unit"
+ android:layout_marginLeft="20dip"
+ android:layout_marginRight="20dip" />
+
+ <TextView
+ android:id="@+id/to_org_unit"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:layout_marginLeft="20dip"
+ android:layout_marginRight="20dip"
+ android:layout_marginBottom="7dip" />
+
+ <!-- Serial number: -->
+ <TextView
+ android:id="@+id/serial_number_header"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:text="@string/serial_number"
+ android:layout_marginLeft="20dip"
+ android:layout_marginRight="20dip" />
+
+ <TextView
+ android:id="@+id/serial_number"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:layout_marginLeft="20dip"
+ android:layout_marginRight="20dip"
+ android:layout_marginBottom="7dip" />
+
+ <!-- Issued by: -->
+ <TextView
+ android:id="@+id/issued_to_header"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:text="@string/issued_by"
+ android:textStyle="bold"
+ android:layout_marginTop="12dip"
+ android:layout_marginLeft="20dip"
+ android:layout_marginRight="20dip"
+ android:layout_marginBottom="7dip" />
+
+ <!-- Common name: -->
+ <TextView
+ android:id="@+id/by_common_header"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/common_name"
+ android:layout_marginLeft="20dip"
+ android:layout_marginRight="20dip" />
+
+ <TextView
+ android:id="@+id/by_common"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:layout_marginLeft="20dip"
+ android:layout_marginRight="20dip"
+ android:layout_marginBottom="7dip" />
+
+ <!-- Organization: -->
+ <TextView
+ android:id="@+id/by_org_header"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:text="@string/org_name"
+ android:layout_marginLeft="20dip"
+ android:layout_marginRight="20dip" />
+
+ <TextView
+ android:id="@+id/by_org"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:layout_marginLeft="20dip"
+ android:layout_marginRight="20dip"
+ android:layout_marginBottom="7dip" />
+
+ <!-- Organizational unit: -->
+ <TextView
+ android:id="@+id/by_org_unit_header"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:text="@string/org_unit"
android:layout_marginLeft="20dip"
- android:layout_marginBottom="12dip" />
-
- <TableLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical">
-
- <!-- Issued to: -->
- <TextView
- android:id="@+id/issued_to_header"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:text="@string/issued_to"
- android:textStyle="bold"
- android:layout_marginLeft="20dip"
- android:layout_marginRight="20dip"
- android:layout_marginBottom="10dip" />
-
- <!-- Common name: -->
- <TextView
- android:id="@+id/to_common_header"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:text="@string/common_name"
- android:gravity="left"
- android:layout_marginLeft="20dip"
- android:layout_marginRight="20dip" />
-
- <TextView
- android:id="@+id/to_common"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:gravity="left"
- android:layout_marginLeft="20dip"
- android:layout_marginRight="20dip"
- android:layout_marginBottom="10dip" />
-
- <!-- Organization: -->
- <TextView
- android:id="@+id/to_org_header"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:text="@string/org_name"
- android:gravity="left"
- android:layout_marginLeft="20dip"
- android:layout_marginRight="20dip" />
-
- <TextView
- android:id="@+id/to_org"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:gravity="left"
- android:layout_marginLeft="20dip"
- android:layout_marginRight="20dip"
- android:layout_marginBottom="10dip" />
-
- <!-- Organizational unit: -->
- <TextView
- android:id="@+id/to_org_unit_header"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:text="@string/org_unit"
- android:gravity="left"
- android:layout_marginLeft="20dip"
- android:layout_marginRight="20dip" />
-
- <TextView
- android:id="@+id/to_org_unit"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:gravity="left"
- android:layout_marginLeft="20dip"
- android:layout_marginRight="20dip"
- android:layout_marginBottom="12dip" />
-
- <!-- Issued by: -->
- <TextView
- android:id="@+id/issued_to_header"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:text="@string/issued_by"
- android:textStyle="bold"
- android:layout_marginLeft="20dip"
- android:layout_marginRight="20dip"
- android:layout_marginBottom="10dip" />
-
- <!-- Common name: -->
- <TextView
- android:id="@+id/by_common_header"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/common_name"
- android:gravity="left"
- android:layout_marginLeft="20dip"
- android:layout_marginRight="20dip" />
-
- <TextView
- android:id="@+id/by_common"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:gravity="left"
- android:layout_marginLeft="20dip"
- android:layout_marginRight="20dip"
- android:layout_marginBottom="10dip" />
-
- <!-- Organization: -->
- <TextView
- android:id="@+id/by_org_header"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:text="@string/org_name"
- android:gravity="left"
- android:layout_marginLeft="20dip"
- android:layout_marginRight="20dip" />
-
- <TextView
- android:id="@+id/by_org"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:gravity="left"
- android:layout_marginLeft="20dip"
- android:layout_marginRight="20dip"
- android:layout_marginBottom="10dip" />
-
- <!-- Organizational unit: -->
- <TextView
- android:id="@+id/by_org_unit_header"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:text="@string/org_unit"
- android:gravity="left"
- android:layout_marginLeft="20dip"
- android:layout_marginRight="20dip" />
-
- <TextView
- android:id="@+id/by_org_unit"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:gravity="left"
- android:layout_marginLeft="20dip"
- android:layout_marginRight="20dip"
- android:layout_marginBottom="12dip" />
-
- <!-- Validity Dates: -->
- <TextView
- android:id="@+id/validity_header"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:text="@string/validity_period"
- android:textStyle="bold"
- android:layout_marginLeft="20dip"
- android:layout_marginRight="20dip"
- android:layout_marginBottom="10dip" />
-
- <!-- Issued On: -->
- <TextView
- android:id="@+id/issued_on_header"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/issued_on"
- android:gravity="left"
- android:layout_marginLeft="20dip"
- android:layout_marginRight="20dip" />
-
- <TextView
- android:id="@+id/issued_on"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:gravity="left"
- android:layout_marginLeft="20dip"
- android:layout_marginRight="20dip"
- android:layout_marginBottom="10dip" />
-
- <!-- Expires On: -->
- <TextView
- android:id="@+id/expires_on_header"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/expires_on"
- android:gravity="left"
- android:layout_marginLeft="20dip"
- android:layout_marginRight="20dip" />
-
- <TextView
- android:id="@+id/expires_on"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:gravity="left"
- android:layout_marginLeft="20dip"
- android:layout_marginRight="20dip"
- android:layout_marginBottom="12dip" />
-
- </TableLayout>
+ android:layout_marginRight="20dip" />
+
+ <TextView
+ android:id="@+id/by_org_unit"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:layout_marginLeft="20dip"
+ android:layout_marginRight="20dip"
+ android:layout_marginBottom="7dip" />
+
+ <!-- Validity Dates: -->
+ <TextView
+ android:id="@+id/validity_header"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:text="@string/validity_period"
+ android:textStyle="bold"
+ android:layout_marginTop="12dip"
+ android:layout_marginLeft="20dip"
+ android:layout_marginRight="20dip"
+ android:layout_marginBottom="7dip" />
+
+ <!-- Issued On: -->
+ <TextView
+ android:id="@+id/issued_on_header"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/issued_on"
+ android:layout_marginLeft="20dip"
+ android:layout_marginRight="20dip" />
+
+ <TextView
+ android:id="@+id/issued_on"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:layout_marginLeft="20dip"
+ android:layout_marginRight="20dip"
+ android:layout_marginBottom="7dip" />
+
+ <!-- Expires On: -->
+ <TextView
+ android:id="@+id/expires_on_header"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/expires_on"
+ android:layout_marginLeft="20dip"
+ android:layout_marginRight="20dip" />
+
+ <TextView
+ android:id="@+id/expires_on"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:layout_marginLeft="20dip"
+ android:layout_marginRight="20dip"
+ android:layout_marginBottom="7dip" />
+
+ <!-- Fingerprints: -->
+ <TextView
+ android:id="@+id/fingerprints"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:text="@string/fingerprints"
+ android:textStyle="bold"
+ android:layout_marginTop="12dip"
+ android:layout_marginLeft="20dip"
+ android:layout_marginRight="20dip"
+ android:layout_marginBottom="7dip" />
+
+ <!-- SHA-256 fingerprint: -->
+ <TextView
+ android:id="@+id/sha256_fingerprint_header"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/sha256_fingerprint"
+ android:layout_marginLeft="20dip"
+ android:layout_marginRight="20dip" />
+
+ <TextView
+ android:id="@+id/sha256_fingerprint"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:layout_marginLeft="20dip"
+ android:layout_marginRight="20dip"
+ android:layout_marginBottom="7dip" />
+
+ <!-- SHA-1 fingerprint: -->
+ <TextView
+ android:id="@+id/sha1_fingerprint_header"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/sha1_fingerprint"
+ android:layout_marginLeft="20dip"
+ android:layout_marginRight="20dip" />
+
+ <TextView
+ android:id="@+id/sha1_fingerprint"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:layout_marginLeft="20dip"
+ android:layout_marginRight="20dip"
+ android:layout_marginBottom="7dip" />
</LinearLayout>
diff --git a/core/res/res/values-w480dp/bools.xml b/core/res/res/values-w480dp/bools.xml
index 8206e79..57a2939 100644
--- a/core/res/res/values-w480dp/bools.xml
+++ b/core/res/res/values-w480dp/bools.xml
@@ -17,7 +17,6 @@
*/
-->
<resources>
- <bool name="allow_action_menu_item_text_with_icon">true</bool>
<bool name="action_bar_embed_tabs">true</bool>
<bool name="split_action_bar_is_narrow">false</bool>
</resources>
diff --git a/core/res/res/values-w480dp/config.xml b/core/res/res/values-w480dp/config.xml
new file mode 100644
index 0000000..269a9b4
--- /dev/null
+++ b/core/res/res/values-w480dp/config.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2011, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<resources>
+ <bool name="config_allowActionMenuItemTextWithIcon">true</bool>
+</resources>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index aa8c510..b92ce6a 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -5210,6 +5210,10 @@
<attr name="divider" />
<!-- Specifies a background drawable for the action bar. -->
<attr name="background" />
+ <!-- Specifies a background drawable for a second stacked row of the action bar. -->
+ <attr name="backgroundStacked" format="reference" />
+ <!-- Specifies a background drawable for the bottom component of a split action bar. -->
+ <attr name="backgroundSplit" format="reference" />
<!-- Specifies a layout for custom navigation. Overrides navigationMode. -->
<attr name="customNavigationLayout" format="reference" />
<!-- Specifies a fixed height. -->
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 03b332e..dd16bd0 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -696,13 +696,6 @@
<p>The default value of this attribute is <code>false</code>. -->
<attr name="restoreAnyVersion" format="boolean" />
- <!-- The agent to use for a *full* backup of the package. Only system applications
- can use this to override the ordinary FullBackupAgent with a custom implementation.
- It's needed strictly for packages with strongly device-specific data, such as the
- Settings provider.
- -->
- <attr name="fullBackupAgent" format="string" />
-
<!-- The default install location defined by an application. -->
<attr name="installLocation">
<!-- Let the system decide ideal install location -->
@@ -800,7 +793,6 @@
<attr name="killAfterRestore" />
<attr name="restoreNeedsApplication" />
<attr name="restoreAnyVersion" />
- <attr name="fullBackupAgent" />
<attr name="neverEncrypt" />
<!-- Request that your application's processes be created with
a large Dalvik heap. This applies to <em>all</em> processes
diff --git a/core/res/res/values/bools.xml b/core/res/res/values/bools.xml
index 9647bb7..e51fc66 100644
--- a/core/res/res/values/bools.xml
+++ b/core/res/res/values/bools.xml
@@ -15,7 +15,6 @@
-->
<resources>
- <bool name="allow_action_menu_item_text_with_icon">false</bool>
<bool name="action_bar_embed_tabs">false</bool>
<bool name="split_action_bar_is_narrow">true</bool>
<bool name="preferences_prefer_dual_pane">false</bool>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 87b9be4..9f05cbc 100755
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -650,4 +650,14 @@
autodetected from the Configuration. -->
<bool name="config_showNavigationBar">false</bool>
+ <!-- Whether action menu items should be displayed in ALLCAPS or not.
+ Defaults to true. If this is not appropriate for specific locales
+ it should be disabled in that locale's resources. -->
+ <bool name="config_actionMenuItemAllCaps">true</bool>
+
+ <!-- Whether action menu items should obey the "withText" showAsAction
+ flag. This may be set to false for situations where space is
+ extremely limited. -->
+ <bool name="config_allowActionMenuItemTextWithIcon">false</bool>
+
</resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 54e484e..75acb37 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1714,10 +1714,6 @@
<public type="attr" name="switchTextOff" />
<public type="attr" name="switchPreferenceStyle" />
- <public type="style" name="TextAppearance.SuggestionHighlight" />
- <public type="style" name="Theme.Holo.SplitActionBarWhenNarrow" />
- <public type="style" name="Theme.Holo.Light.SplitActionBarWhenNarrow" />
-
<public type="attr" name="textSuggestionsWindowStyle" />
<public type="attr" name="textEditSuggestionsBottomWindowLayout" />
<public type="attr" name="textEditSuggestionsTopWindowLayout" />
@@ -1725,7 +1721,6 @@
<public type="attr" name="layoutDirection" />
- <public type="attr" name="fullBackupAgent" />
<public type="attr" name="suggestionsEnabled" />
<public type="attr" name="rowCount" />
@@ -1737,7 +1732,6 @@
<public type="attr" name="layout_row" />
<public type="attr" name="layout_rowSpan" />
-
<public type="attr" name="layout_columnSpan" />
<public type="attr" name="layout_widthSpec" />
@@ -1778,14 +1772,38 @@
<public type="attr" name="actionBarSplitStyle" />
+ <public type="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/strings.xml b/core/res/res/values/strings.xml
index 9897c80..50f8df7 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -2989,6 +2989,14 @@
<string name="issued_on">Issued on:</string>
<!-- Label for an information field on an SSL Certificate Dialog -->
<string name="expires_on">Expires on:</string>
+ <!-- Label for an information field on an SSL Certificate Dialog -->
+ <string name="serial_number">Serial number:</string>
+ <!-- Label for an information field on an SSL Certificate Dialog -->
+ <string name="fingerprints">Fingerprints:</string>
+ <!-- Label for an information field on an SSL Certificate Dialog -->
+ <string name="sha256_fingerprint">SHA-256 fingerprint:</string>
+ <!-- Label for an information field on an SSL Certificate Dialog -->
+ <string name="sha1_fingerprint">SHA-1 fingerprint:</string>
<!-- Title for a button to expand the list of activities in ActivityChooserView [CHAR LIMIT=25] -->
<string name="activity_chooser_view_see_all">See all...</string>
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 5244b74..9ee4b6a 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -1304,13 +1304,37 @@
<item name="android:textSize">@android:dimen/action_bar_subtitle_text_size</item>
</style>
+ <style name="TextAppearance.Holo.Widget.ActionBar.Title.Inverse"
+ parent="TextAppearance.Holo.Medium.Inverse">
+ <item name="android:textSize">@android:dimen/action_bar_title_text_size</item>
+ </style>
+
+ <style name="TextAppearance.Holo.Widget.ActionBar.Subtitle.Inverse"
+ parent="TextAppearance.Holo.Small.Inverse">
+ <item name="android:textSize">@android:dimen/action_bar_subtitle_text_size</item>
+ </style>
+
<style name="TextAppearance.Holo.Widget.ActionMode">
</style>
- <style name="TextAppearance.Holo.Widget.ActionMode.Title" parent="TextAppearance.Widget.ActionMode.Title">
+ <style name="TextAppearance.Holo.Widget.ActionMode.Title"
+ parent="TextAppearance.Holo.Medium">
+ <item name="android:textSize">@android:dimen/action_bar_title_text_size</item>
+ </style>
+
+ <style name="TextAppearance.Holo.Widget.ActionMode.Subtitle"
+ parent="TextAppearance.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 78e9975..23111e6 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -283,7 +283,7 @@
<item name="actionBarSplitStyle">?android:attr/actionBarStyle</item>
<item name="actionBarSize">@dimen/action_bar_default_height</item>
<item name="actionModePopupWindowStyle">?android:attr/popupWindowStyle</item>
- <item name="actionMenuTextAppearance">?android:attr/textAppearanceMedium</item>
+ <item name="actionMenuTextAppearance">?android:attr/textAppearanceSmall</item>
<item name="actionMenuTextColor">?android:attr/textColorPrimary</item>
<item name="dividerVertical">@drawable/divider_vertical_dark</item>
@@ -1365,6 +1365,71 @@
</style>
+ <!-- Variant of the holographic (dark) theme that has a solid (opaque) action bar. -->
+ <style name="Theme.Holo.SolidActionBar">
+ <item name="android:actionBarStyle">@android:style/Widget.Holo.ActionBar.Solid</item>
+ <item name="android:windowContentOverlay">@android:drawable/ab_solid_shadow_holo</item>
+ </style>
+
+ <!-- Variant of the holographic (light) theme that has a solid (opaque) action bar. -->
+ <style name="Theme.Holo.Light.SolidActionBar">
+ <item name="android:actionBarStyle">@android:style/Widget.Holo.Light.ActionBar.Solid</item>
+ <item name="android:windowContentOverlay">@android:drawable/ab_solid_shadow_holo</item>
+ </style>
+
+ <!-- Variant of the holographic (light) theme that has a solid (opaque) action bar
+ with an inverse color profile. The dark action bar sharply stands out against
+ the light content. -->
+ <style name="Theme.Holo.Light.SolidActionBar.Inverse">
+ <item name="android:windowContentOverlay">@android:drawable/title_bar_shadow</item>
+ <item name="android:actionBarStyle">@android:style/Widget.Holo.Light.ActionBar.Solid.Inverse</item>
+
+ <item name="actionDropDownStyle">@android:style/Widget.Holo.Spinner.DropDown.ActionBar</item>
+ <item name="actionButtonStyle">@android:style/Widget.Holo.ActionButton</item>
+ <item name="actionOverflowButtonStyle">@android:style/Widget.Holo.ActionButton.Overflow</item>
+ <item name="actionModeBackground">@android:drawable/cab_background_holo_dark</item>
+ <item name="actionModeCloseDrawable">@android:drawable/cab_ic_close_holo</item>
+ <item name="actionBarTabStyle">@style/Widget.Holo.Light.ActionBar.TabView.Inverse</item>
+ <item name="actionBarTabBarStyle">@style/Widget.Holo.Light.ActionBar.TabBar.Inverse</item>
+ <item name="actionBarTabTextStyle">@style/Widget.Holo.Light.ActionBar.TabText.Inverse</item>
+ <item name="actionMenuTextColor">?android:attr/textColorPrimaryInverse</item>
+ <item name="actionModeStyle">@style/Widget.Holo.Light.ActionMode.Inverse</item>
+ <item name="actionModeCloseButtonStyle">@style/Widget.Holo.ActionButton.CloseMode</item>
+ <item name="actionModePopupWindowStyle">@android:style/Widget.Holo.PopupWindow.ActionMode</item>
+
+ <item name="actionModeCutDrawable">@android:drawable/ic_menu_cut_holo_dark</item>
+ <item name="actionModeCopyDrawable">@android:drawable/ic_menu_copy_holo_dark</item>
+ <item name="actionModePasteDrawable">@android:drawable/ic_menu_paste_holo_dark</item>
+ <item name="actionModeSelectAllDrawable">@android:drawable/ic_menu_selectall_holo_dark</item>
+ <item name="actionModeShareDrawable">@android:drawable/ic_menu_share_holo_dark</item>
+ <item name="actionModeFindDrawable">@android:drawable/ic_menu_find_holo_dark</item>
+ <item name="actionModeWebSearchDrawable">@android:drawable/ic_menu_search_holo_dark</item>
+ </style>
+
+ <!-- Variant of the holographic (dark) theme that has a solid
+ (opaque) action bar. The action bar will split across both
+ the top and bottom of the screen when the screen is
+ especially constrained for horizontal space. -->
+ <style name="Theme.Holo.SolidActionBar.SplitActionBarWhenNarrow">
+ <item name="android:windowSplitActionBar">@android:bool/split_action_bar_is_narrow</item>
+ </style>
+
+ <!-- Variant of the holographic (light) theme that has a solid
+ (opaque) action bar. The action bar will split across both
+ the top and bottom of the screen when the screen is
+ especially constrained for horizontal space. -->
+ <style name="Theme.Holo.Light.SolidActionBar.SplitActionBarWhenNarrow">
+ <item name="android:windowSplitActionBar">@android:bool/split_action_bar_is_narrow</item>
+ </style>
+
+ <!-- Variant of the holographic (light) theme that has a solid (opaque) action bar
+ with an inverse color profile. The dark action bar sharply stands out against
+ the light content. The action bar will split across both the top and bottom of
+ the screen when the screen is especially constrained for horizontal space. -->
+ <style name="Theme.Holo.Light.SolidActionBar.Inverse.SplitActionBarWhenNarrow">
+ <item name="android:windowSplitActionBar">@android:bool/split_action_bar_is_narrow</item>
+ </style>
+
<!-- Variant of the holographic (dark) theme with no action bar. -->
<style name="Theme.Holo.NoActionBar">
<item name="android:windowActionBar">false</item>
diff --git a/docs/html/guide/topics/graphics/index.jd b/docs/html/guide/topics/graphics/index.jd
index be1b0fc..2490e39 100644
--- a/docs/html/guide/topics/graphics/index.jd
+++ b/docs/html/guide/topics/graphics/index.jd
@@ -14,13 +14,20 @@ page.title=Graphics
</ol>
</li>
</ol>
+ <h2>See also</h2>
+ <ol>
+ <li><a href="{@docRoot}guide/topics/graphics/opengl.html">3D with OpenGL</a></li>
+ <li><a href="{@docRoot}guide/topics/renderscript/index.html">RenderScript</a></li>
+ </ol>
</div>
</div>
-<p>Android graphics are powered by a custom 2D graphics library and OpenGL ES 1.0
-for high performance 3D graphics. The most common 2D graphics APIs can be found in the
-{@link android.graphics.drawable drawable package}. OpenGL APIs are available
-from the Khronos {@link javax.microedition.khronos.opengles OpenGL ES package},
-plus some Android {@link android.opengl OpenGL utilities}.</p>
+
+<p>Android graphics are powered by a custom 2D graphics library, and the framework provides
+support for high performance 3D graphics in the form of OpenGL ES and RenderScript. The most
+common 2D graphics APIs can be found in the {@link android.graphics.drawable drawable package}.
+OpenGL APIs are available from the Khronos {@link javax.microedition.khronos.opengles OpenGL ES} and
+the {@link android.opengl} packages. The RenderScript APIs are available in the
+{@link android.renderscript} package.</p>
<p>When starting a project, it's important to consider exactly what your graphical demands will be.
Varying graphical tasks are best accomplished with varying techniques. For example, graphics and animations
@@ -32,10 +39,10 @@ and which tasks they're best suited for.</p>
<p>If you're specifically looking for information on drawing 3D graphics, this page won't
help a lot. However, the information below about how to <a href="#draw-with-canvas">Draw with a
-Canvas</a> (and the section on SurfaceView),
-will give you a quick idea of how you should draw to the View hierarchy. For more information
-on Android's 3D graphic utilities (provided by the OpenGL ES API),
-read <a href="opengl.html">3D with OpenGL</a> and refer to other OpenGL documentation.</p>
+Canvas</a> (and the section on SurfaceView), will give you a quick idea of how you should draw to
+the View hierarchy. For more information on Android's 3D graphics APIs, see
+the <a href="opengl.html">3D with OpenGL</a> and
+<a href="{@docRoot}guide/topics/renderscript/index.html">RenderScript</a> documents.</p>
<h2 id="options">Consider your Options</h2>
diff --git a/docs/html/guide/topics/graphics/opengl.jd b/docs/html/guide/topics/graphics/opengl.jd
index 9f88954..cc467f2 100644
--- a/docs/html/guide/topics/graphics/opengl.jd
+++ b/docs/html/guide/topics/graphics/opengl.jd
@@ -3,51 +3,215 @@ parent.title=Graphics
parent.link=index.html
@jd:body
+<div id="qv-wrapper">
+ <div id="qv">
+ <h2>In this document</h2>
+
+ <ol>
+ <li><a href="#basics">The Basics</a></li>
+ <li><a href="#compatibility">OpenGL Versions and Device Compatibility</a>
+ <ol>
+ <li><a href="#textures">Texture Compression Support</a></li>
+ <li><a href="#declare-compression">Declaring Use of Compressed Textures</a></li>
+ </ol>
+ </li>
+ </ol>
+ <h2>Key classes</h2>
+ <ol>
+ <li>{@link android.opengl.GLSurfaceView}</li>
+ <li>{@link android.opengl.GLSurfaceView.Renderer}</li>
+ <li>{@link javax.microedition.khronos.opengles}</li>
+ <li>{@link android.opengl}</li>
+ </ol>
+ <h2>Related Samples</h2>
+ <ol>
+ <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/graphics/
+GLSurfaceViewActivity.html">GLSurfaceViewActivity</a></li>
+ <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/graphics/
+GLES20Activity.html">GLES20Activity</a></li>
+ <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/graphics/
+TouchRotateActivity.html">TouchRotateActivity</a></li>
+ <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/graphics/
+CompressedTextureActivity.html">Compressed Textures</a></li>
+ </ol>
+ <h2>See also</h2>
+ <ol>
+ <li><a href="{@docRoot}resources/articles/glsurfaceview.html">Introducing
+GLSurfaceView</a></li>
+ <li><a href="http://www.khronos.org/opengles/">OpenGL ES</a></li>
+ <li><a href="http://www.khronos.org/opengles/1_X/">OpenGL ES 1.x Specification</a></li>
+ <li><a href="http://www.khronos.org/opengles/2_X/">OpenGL ES 2.x specification</a></li>
+ </ol>
+ </div>
+</div>
-<p>Android includes support for high performance 3D graphics
-via the OpenGL API&mdash;specifically, the OpenGL ES API.</p>
+<p>Android includes support for high performance 2D and 3D graphics with the Open Graphics Library
+(OpenGL) API&mdash;specifically, the OpenGL ES API. OpenGL is a cross-platform graphics API that
+specifies a standard software interface for 3D graphics processing hardware. OpenGL ES is a flavor
+of the OpenGL specification intended for embedded devices. The OpenGL ES 1.0 and 1.1 API
+specifications have been supported since Android 1.0. Beginning with Android 2.2 (API
+Level 8), the framework supports the OpenGL ES 2.0 API specification.</p>
-<p>OpenGL ES is a flavor of the OpenGL specification intended for embedded devices. Versions of <a
-href="http://www.khronos.org/opengles/">OpenGL ES</a> are loosely peered to versions of the primary
-OpenGL standard. Beginning with Android 2.2, the platform supports OpenGL ES 2.0 (with
-backward compatibility support for OpenGL ES 1.1). For information about the relative number of
-Android-powered devices that support a given version of OpenGL ES, see the <a
-href="http://developer.android.com/resources/dashboard/opengl.html">OpenGL ES Versions</a>
-dashboard.</p>
+<p class="note"><b>Note:</b> The specific API provided by the Android framework is similar to the
+ J2ME JSR239 OpenGL ES API, but is not identical. If you are familiar with J2ME JSR239
+ specification, be alert for variations.</p>
-<p>The specific API provided by Android is similar to the J2ME JSR239 OpenGL
-ES API. However, it may not be identical, so watch out for deviations.</p>
-<h2>Using the API</h2>
+<h2 id="basics">The Basics</h2>
-<p>Here's how to use the API at an extremely high level:</p>
+<p>Android supports OpenGL both through its framework API and the Native Development
+Kit (NDK). This topic focuses on the Android framework interfaces. For more information about the
+NDK, see the <a href="{@docRoot}sdk/ndk/index.html">Android NDK</a>.
-<ol>
-<li>Write a custom {@link android.view.View} subclass.</li>
-<li>Obtain a handle to an OpenGLContext, which provides access to the OpenGL functionality.</li>
-<li>In your View's {@link android.view.View#onDraw onDraw()} method, get a handle to a GL object,
-and use its methods to perform GL operations.</li>
-</ol>
+<p>
+ There are two foundational classes in the Android framework that let you create and manipulate
+graphics with the OpenGL ES API: {@link android.opengl.GLSurfaceView} and {@link
+android.opengl.GLSurfaceView.Renderer}. If your goal is to use OpenGL in your Android application,
+understanding how to implement these classes in an activity should be your first objective.
+</p>
+
+<dl>
+ <dt>{@link android.opengl.GLSurfaceView}</dt>
+ <dd>This class is a container on which you can draw and manipulate objects using OpenGL API calls.
+ This class is similar in function to a {@link android.view.SurfaceView}, except that it is
+ specifically for use with OpenGL. You can use this class by simply creating an instance of
+ {@link android.opengl.GLSurfaceView} and adding your
+ {@link android.opengl.GLSurfaceView.Renderer Renderer} to it. However, if you want to capture
+ touch screen events, you should extend the {@link android.opengl.GLSurfaceView} class to
+ implement the touch listeners, as shown in the <a
+href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/graphics/TouchRotateActivity
+.html">TouchRotateActivity</a> sample.</dd>
+
+ <dt>{@link android.opengl.GLSurfaceView.Renderer}</dt>
+ <dd>This interface defines the methods required for drawing graphics in an OpenGL {@link
+ android.opengl.GLSurfaceView}. You must provide an implementation of this interface as a
+ separate class and attach it to your {@link android.opengl.GLSurfaceView} instance using
+ {@link android.opengl.GLSurfaceView#setRenderer(android.opengl.GLSurfaceView.Renderer)
+ GLSurfaceView.setRenderer()}.
+
+ <p>The {@link android.opengl.GLSurfaceView.Renderer} interface requires that you implement the
+ following methods:</p>
+ <ul>
+ <li>
+ {@link
+ android.opengl.GLSurfaceView.Renderer#onSurfaceCreated(javax.microedition.khronos.opengles.GL10,
+ javax.microedition.khronos.egl.EGLConfig) onSurfaceCreated()}: The system calls this
+ method once, when creating the {@link android.opengl.GLSurfaceView}. Use this method to perform
+ actions that need to happen only once, such as setting OpenGL environment parameters or
+ initializing OpenGL graphic objects.
+ </li>
+ <li>
+ {@link
+ android.opengl.GLSurfaceView.Renderer#onDrawFrame(javax.microedition.khronos.opengles.GL10)
+ onDrawFrame()}: The system calls this method on each redraw of the {@link
+ android.opengl.GLSurfaceView}. Use this method as the primary execution point for
+ drawing (and re-drawing) graphic objects.</li>
+ <li>
+ {@link
+ android.opengl.GLSurfaceView.Renderer#onSurfaceChanged(javax.microedition.khronos.opengles.GL10,
+ int, int) onSurfaceChanged()}: The system calls this method when the {@link
+ android.opengl.GLSurfaceView} geometry changes, including changes in size of the {@link
+ android.opengl.GLSurfaceView} or orientation of the device screen. For example, the system calls
+ this method when the device changes from portrait to landscape orientation. Use this method to
+ respond to changes in the {@link android.opengl.GLSurfaceView} container.
+ </li>
+ </ul>
+ </dd>
+</dl>
+
+<p>Once you have established a container view for OpenGL using {@link
+android.opengl.GLSurfaceView} and {@link android.opengl.GLSurfaceView.Renderer}, you can begin
+calling OpenGL APIs using the following classes:</p>
+
+<ul>
+ <li>OpenGL ES 1.0/1.1 API Packages
+ <ul>
+ <li>{@link javax.microedition.khronos.opengles} - This package provides the standard
+implementation of OpenGL ES 1.0 and 1.1.
+ <ul>
+ <li>{@link javax.microedition.khronos.opengles.GL10}</li>
+ <li>{@link javax.microedition.khronos.opengles.GL10Ext}</li>
+ <li>{@link javax.microedition.khronos.opengles.GL11}</li>
+ <li>{@link javax.microedition.khronos.opengles.GL11Ext}</li>
+ <li>{@link javax.microedition.khronos.opengles.GL11ExtensionPack}</li>
+ </ul>
+ </li>
+ <li>{@link android.opengl} - This package provides a static interface to the OpenGL classes
+ above. These interfaces were added with Android 1.6 (API Level 4).
+ <ul>
+ <li>{@link android.opengl.GLES10}</li>
+ <li>{@link android.opengl.GLES10Ext}</li>
+ <li>{@link android.opengl.GLES11}</li>
+ <li>{@link android.opengl.GLES10Ext}</li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+ <li>OpenGL ES 2.0 API Class
+ <ul>
+ <li>{@link android.opengl.GLES20 android.opengl.GLES20}</li>
+ </ul>
+ </li>
+</ul>
-<p>Several samples using OpenGL ES are available in the <a
-href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/graphics/index.html">API
-Demos</a> sample application.
+<h2 id="compatibility">OpenGL Versions and Device Compatibility</h2>
+
+<p>
+ The OpenGL ES 1.0 and 1.1 API specifications have been supported since Android 1.0.
+Beginning with Android 2.2 (API Level 8), the framework supports the OpenGL ES 2.0 API
+specification. OpenGL ES 2.0 is supported by most Android devices and is recommended for new
+applications being developed with OpenGL. For information about the relative number of
+Android-powered devices that support a given version of OpenGL ES, see the <a
+href="{@docRoot}resources/dashboard/opengl.html">OpenGL ES Versions Dashboard</a>.</p>
+
+<h3 id="textures">Texture compression support</h3>
+<p>Texture compression can significantly increase the performance of your OpenGL application by
+reducing memory requirements and making more efficient use of memory bandwidth. The Android
+framework provides support for the ETC1 compression format as a standard feature, including a {@link
+android.opengl.ETC1Util} utility class and the {@code etc1tool} compression tool (located in your
+Android SDK at {@code &lt;sdk&gt;/tools/}).</p>
+
+<p>For an example of an Android application that uses texture compression, see the <a
+href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/graphics/
+CompressedTextureActivity.html">CompressedTextureActivity</a> code sample.
</p>
-<p>A summary of how to actually write 3D applications using OpenGL is
-beyond the scope of this text and is left as an exercise for the reader.</p>
+<p>To check if the ETC1 format is supported on a device, call the {@link
+android.opengl.ETC1Util#isETC1Supported() ETC1Util.isETC1Supported()} method.</p>
-<h2>Links to Additional Information</h2>
+<p class="note"><b>Note:</b> The ETC1 texture compression format does not support textures with an
+alpha channel. If your application requires textures with an alpha channel, you should
+investigate other texture compression formats available on your target devices.</p>
-<p>Information about OpenGL ES can be
-found at <a title="http://www.khronos.org/opengles/"
-href="http://www.khronos.org/opengles/">http://www.khronos.org/opengles/</a>.</p>
+<p>Beyond the ETC1 format, Android devices have varied support for texture compression based on
+their GPU chipsets. You should investigate texture compression support on the the devices you are
+are targeting to determine what compression types your application should support.</p>
-<p>Information specifically
-about OpenGL ES 1.0 (including a detailed specification) can be found
-at <a title="http://www.khronos.org/opengles/1_X/"
-href="http://www.khronos.org/opengles/1_X/">http://www.khronos.org/opengles/1_X/</a>.</p>
+<p>To determine if texture compression formats other than ETC1 are supported on a particular
+device:</p>
+<ol>
+ <li>Run the following code on your target devices to determine what texture compression
+formats are supported:
+<pre>
+ String extensions = javax.microedition.khronos.opengles.GL10.glGetString(GL10.GL_EXTENSIONS);
+</pre>
+ <p class="warning"><b>Warning:</b> The results of this call vary by device! You must run this
+call on several target devices to determine what compression types are commonly supported on
+your target devices.</p>
+ </li>
+ <li>Review the output of this method to determine what extensions are supported on the
+device.</li>
+</ol>
-<p>The documentation for the Android OpenGL ES implementations are available in {@link
-android.opengl} and {@link javax.microedition.khronos.opengles}.</p>
+<h3 id="declare-compression">Declaring compressed textures</h3>
+<p>Once you have decided which texture compression types your application will support, you
+must declare them in your manifest file using <a
+href="{@docRoot}guide/topics/manifest/supports-gl-texture-element.html">
+&lt;supports-gl-texture&gt;</a>. Declaring this information in your manifest file hides your
+application from users with devices that do not support at least one of your declared
+compression types. For more information on how Android Market filtering works for texture
+compressions, see the <a
+href="{@docRoot}guide/topics/manifest/supports-gl-texture-element.html#market-texture-filtering">
+Android Market and texture compression filtering</a> section of the {@code
+&lt;supports-gl-texture&gt;} documentation.
diff --git a/docs/html/guide/topics/usb/adk.jd b/docs/html/guide/topics/usb/adk.jd
index 2e172f5..b5a3f30 100644
--- a/docs/html/guide/topics/usb/adk.jd
+++ b/docs/html/guide/topics/usb/adk.jd
@@ -326,7 +326,7 @@ page.title=Android Open Accessory Development Kit
<li>To open the firmware code (a sketch), click <strong>File &gt; Open</strong> and select
<code>firmware/demokit/demokit.pde</code>.</li>
- <li>Click <strong>Sketch &gt; Compile/Verify</strong> to ensure that the sketch has no
+ <li>Click <strong>Sketch &gt; Verify/Compile</strong> to ensure that the sketch has no
errors.</li>
<li>Select <strong>File &gt; Upload to I/O Board</strong>. When Arduino outputs <strong>Done
@@ -356,7 +356,8 @@ page.title=Android Open Accessory Development Kit
<li>In the <strong>Project name:</strong> field, type DemoKit.</li>
<li>Choose <strong>Create project from existing source</strong>, click <strong>Browse</strong>,
- select the <code>app</code> directory, and click <strong>Finish</strong>.</li>
+ select the <code>app</code> directory, click <strong>Open</strong> to close that dialog and then
+ click <strong>Finish</strong>.</li>
<li>For Build Target, select <strong>Google APIs</strong> (Platform 2.3.3, API Level 10).
diff --git a/docs/html/resources/resources-data.js b/docs/html/resources/resources-data.js
index e8c9ae7..0fc10bf 100644
--- a/docs/html/resources/resources-data.js
+++ b/docs/html/resources/resources-data.js
@@ -726,6 +726,16 @@ var ANDROID_RESOURCES = [
en: 'Binding data to views using XML Adapters examples.'
}
},
+ {
+ tags: ['sample', 'new', 'accessibility'],
+ path: 'samples/TtsEngine/index.html',
+ title: {
+ en: 'Text To Speech Engine'
+ },
+ description: {
+ en: 'An example Text To Speech engine written using the android text to speech engine API.'
+ }
+ },
/////////////////
/// TUTORIALS ///
diff --git a/include/media/mediametadataretriever.h b/include/media/mediametadataretriever.h
index 28f305d..9aa6700 100644
--- a/include/media/mediametadataretriever.h
+++ b/include/media/mediametadataretriever.h
@@ -53,6 +53,7 @@ enum {
METADATA_KEY_VIDEO_HEIGHT = 19,
METADATA_KEY_BITRATE = 20,
METADATA_KEY_TIMED_TEXT_LANGUAGES = 21,
+ METADATA_KEY_IS_DRM = 22,
// Add more here...
};
diff --git a/include/media/stagefright/MediaExtractor.h b/include/media/stagefright/MediaExtractor.h
index a82106e..eb45237 100644
--- a/include/media/stagefright/MediaExtractor.h
+++ b/include/media/stagefright/MediaExtractor.h
@@ -56,7 +56,12 @@ public:
virtual uint32_t flags() const;
// for DRM
- virtual void setDrmFlag(bool flag) {};
+ virtual void setDrmFlag(bool flag) {
+ mIsDrm = flag;
+ };
+ virtual bool getDrmFlag() {
+ return mIsDrm;
+ }
virtual char* getDrmTrackInfo(size_t trackID, int *len) {
return NULL;
}
@@ -66,6 +71,8 @@ protected:
virtual ~MediaExtractor() {}
private:
+ bool mIsDrm;
+
MediaExtractor(const MediaExtractor &);
MediaExtractor &operator=(const MediaExtractor &);
};
diff --git a/include/surfaceflinger/IGraphicBufferAlloc.h b/include/surfaceflinger/IGraphicBufferAlloc.h
index e1b6b57..d3b2062 100644
--- a/include/surfaceflinger/IGraphicBufferAlloc.h
+++ b/include/surfaceflinger/IGraphicBufferAlloc.h
@@ -37,7 +37,7 @@ public:
/* Create a new GraphicBuffer for the client to use.
*/
virtual sp<GraphicBuffer> createGraphicBuffer(uint32_t w, uint32_t h,
- PixelFormat format, uint32_t usage) = 0;
+ PixelFormat format, uint32_t usage, status_t* error) = 0;
};
// ----------------------------------------------------------------------------
diff --git a/include/utils/threads.h b/include/utils/threads.h
index 0bd69cf..c8e9c04 100644
--- a/include/utils/threads.h
+++ b/include/utils/threads.h
@@ -133,13 +133,13 @@ extern pid_t androidGetTid();
// Change the scheduling group of a particular thread. The group
// should be one of the ANDROID_TGROUP constants. Returns BAD_VALUE if
// grp is out of range, else another non-zero value with errno set if
-// the operation failed.
+// the operation failed. Thread ID zero means current thread.
extern int androidSetThreadSchedulingGroup(pid_t tid, int grp);
// Change the priority AND scheduling group of a particular thread. The priority
// should be one of the ANDROID_PRIORITY constants. Returns INVALID_OPERATION
// if the priority set failed, else another value if just the group set failed;
-// in either case errno is set.
+// in either case errno is set. Thread ID zero means current thread.
extern int androidSetThreadPriority(pid_t tid, int prio);
#ifdef __cplusplus
@@ -510,6 +510,10 @@ public:
// that case.
status_t requestExitAndWait();
+ // Wait until this object's thread exits. Returns immediately if not yet running.
+ // Do not call from this object's thread; will return WOULD_BLOCK in that case.
+ status_t join();
+
protected:
// exitPending() returns true if requestExit() has been called.
bool exitPending() const;
diff --git a/keystore/java/android/security/KeyChain.java b/keystore/java/android/security/KeyChain.java
index e91bcab..6229331 100644
--- a/keystore/java/android/security/KeyChain.java
+++ b/keystore/java/android/security/KeyChain.java
@@ -81,6 +81,13 @@ 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/libs/gui/IGraphicBufferAlloc.cpp b/libs/gui/IGraphicBufferAlloc.cpp
index 0cd51da..30f8d00 100644
--- a/libs/gui/IGraphicBufferAlloc.cpp
+++ b/libs/gui/IGraphicBufferAlloc.cpp
@@ -43,7 +43,7 @@ public:
}
virtual sp<GraphicBuffer> createGraphicBuffer(uint32_t w, uint32_t h,
- PixelFormat format, uint32_t usage) {
+ PixelFormat format, uint32_t usage, status_t* error) {
Parcel data, reply;
data.writeInterfaceToken(IGraphicBufferAlloc::getInterfaceDescriptor());
data.writeInt32(w);
@@ -52,14 +52,15 @@ public:
data.writeInt32(usage);
remote()->transact(CREATE_GRAPHIC_BUFFER, data, &reply);
sp<GraphicBuffer> graphicBuffer;
- bool nonNull = (bool)reply.readInt32();
- if (nonNull) {
+ status_t result = reply.readInt32();
+ if (result == NO_ERROR) {
graphicBuffer = new GraphicBuffer();
reply.read(*graphicBuffer);
// reply.readStrongBinder();
// here we don't even have to read the BufferReference from
// the parcel, it'll die with the parcel.
}
+ *error = result;
return graphicBuffer;
}
};
@@ -91,8 +92,10 @@ status_t BnGraphicBufferAlloc::onTransact(
uint32_t h = data.readInt32();
PixelFormat format = data.readInt32();
uint32_t usage = data.readInt32();
- sp<GraphicBuffer> result(createGraphicBuffer(w, h, format, usage));
- reply->writeInt32(result != 0);
+ status_t error;
+ sp<GraphicBuffer> result =
+ createGraphicBuffer(w, h, format, usage, &error);
+ reply->writeInt32(error);
if (result != 0) {
reply->write(*result);
// We add a BufferReference to this parcel to make sure the
diff --git a/libs/gui/SurfaceTexture.cpp b/libs/gui/SurfaceTexture.cpp
index 3bf6477..886a3fb 100644
--- a/libs/gui/SurfaceTexture.cpp
+++ b/libs/gui/SurfaceTexture.cpp
@@ -352,11 +352,13 @@ status_t SurfaceTexture::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h,
((uint32_t(buffer->usage) & usage) != usage))
{
usage |= GraphicBuffer::USAGE_HW_TEXTURE;
+ status_t error;
sp<GraphicBuffer> graphicBuffer(
- mGraphicBufferAlloc->createGraphicBuffer(w, h, format, usage));
+ mGraphicBufferAlloc->createGraphicBuffer(
+ w, h, format, usage, &error));
if (graphicBuffer == 0) {
LOGE("dequeueBuffer: SurfaceComposer::createGraphicBuffer failed");
- return NO_MEMORY;
+ return error;
}
if (updateFormat) {
mPixelFormat = format;
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index 450cdf1..ce587b3 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -31,13 +31,13 @@ protected:
ASSERT_EQ(NO_ERROR, mComposerClient->initCheck());
mSurfaceControl = mComposerClient->createSurface(
- String8("Test Surface"), 0, 32, 32, PIXEL_FORMAT_RGB_888, 0);
+ String8("Test Surface"), 0, 32, 32, PIXEL_FORMAT_RGBA_8888, 0);
ASSERT_TRUE(mSurfaceControl != NULL);
ASSERT_TRUE(mSurfaceControl->isValid());
SurfaceComposerClient::openGlobalTransaction();
- ASSERT_EQ(NO_ERROR, mSurfaceControl->setLayer(30000));
+ ASSERT_EQ(NO_ERROR, mSurfaceControl->setLayer(0x7fffffff));
ASSERT_EQ(NO_ERROR, mSurfaceControl->show());
SurfaceComposerClient::closeGlobalTransaction();
@@ -84,7 +84,7 @@ TEST_F(SurfaceTest, ScreenshotsOfProtectedBuffersFail) {
PixelFormat fmt=0;
sp<ISurfaceComposer> sf(ComposerService::getComposerService());
ASSERT_EQ(NO_ERROR, sf->captureScreen(0, &heap, &w, &h, &fmt, 64, 64, 0,
- 40000));
+ 0x7fffffff));
ASSERT_TRUE(heap != NULL);
// Set the PROTECTED usage bit and verify that the screenshot fails. Note
@@ -94,6 +94,18 @@ TEST_F(SurfaceTest, ScreenshotsOfProtectedBuffersFail) {
GRALLOC_USAGE_PROTECTED));
ASSERT_EQ(NO_ERROR, native_window_set_buffer_count(anw.get(), 3));
ANativeWindowBuffer* buf = 0;
+
+ status_t err = anw->dequeueBuffer(anw.get(), &buf);
+ if (err) {
+ // we could fail if GRALLOC_USAGE_PROTECTED is not supported.
+ // that's okay as long as this is the reason for the failure.
+ // try again without the GRALLOC_USAGE_PROTECTED bit.
+ ASSERT_EQ(NO_ERROR, native_window_set_usage(anw.get(), 0));
+ ASSERT_EQ(NO_ERROR, anw->dequeueBuffer(anw.get(), &buf));
+ return;
+ }
+ ASSERT_EQ(NO_ERROR, anw->cancelBuffer(anw.get(), buf));
+
for (int i = 0; i < 4; i++) {
// Loop to make sure SurfaceFlinger has retired a protected buffer.
ASSERT_EQ(NO_ERROR, anw->dequeueBuffer(anw.get(), &buf));
@@ -103,7 +115,7 @@ TEST_F(SurfaceTest, ScreenshotsOfProtectedBuffersFail) {
heap = 0;
w = h = fmt = 0;
ASSERT_EQ(INVALID_OPERATION, sf->captureScreen(0, &heap, &w, &h, &fmt,
- 64, 64, 0, 40000));
+ 64, 64, 0, 0x7fffffff));
ASSERT_TRUE(heap == NULL);
// XXX: This should not be needed, but it seems that the new buffers don't
@@ -126,7 +138,7 @@ TEST_F(SurfaceTest, ScreenshotsOfProtectedBuffersFail) {
heap = 0;
w = h = fmt = 0;
ASSERT_EQ(NO_ERROR, sf->captureScreen(0, &heap, &w, &h, &fmt, 64, 64, 0,
- 40000));
+ 0x7fffffff));
ASSERT_TRUE(heap != NULL);
}
diff --git a/libs/utils/Threads.cpp b/libs/utils/Threads.cpp
index 15bb1d2..50312e7 100644
--- a/libs/utils/Threads.cpp
+++ b/libs/utils/Threads.cpp
@@ -316,6 +316,10 @@ int androidSetThreadSchedulingGroup(pid_t tid, int grp)
#if defined(HAVE_PTHREADS)
pthread_once(&gDoSchedulingGroupOnce, checkDoSchedulingGroup);
if (gDoSchedulingGroup) {
+ // set_sched_policy does not support tid == 0
+ if (tid == 0) {
+ tid = androidGetTid();
+ }
if (set_sched_policy(tid, (grp == ANDROID_TGROUP_BG_NONINTERACT) ?
SP_BACKGROUND : SP_FOREGROUND)) {
return PERMISSION_DENIED;
@@ -842,6 +846,25 @@ status_t Thread::requestExitAndWait()
return mStatus;
}
+status_t Thread::join()
+{
+ Mutex::Autolock _l(mLock);
+ if (mThread == getThreadId()) {
+ LOGW(
+ "Thread (this=%p): don't call join() from this "
+ "Thread object's thread. It's a guaranteed deadlock!",
+ this);
+
+ return WOULD_BLOCK;
+ }
+
+ while (mRunning == true) {
+ mThreadExitedCondition.wait(mLock);
+ }
+
+ return mStatus;
+}
+
bool Thread::exitPending() const
{
Mutex::Autolock _l(mLock);
diff --git a/media/java/android/media/MediaFile.java b/media/java/android/media/MediaFile.java
index 7634c6c..6df2f73 100644
--- a/media/java/android/media/MediaFile.java
+++ b/media/java/android/media/MediaFile.java
@@ -214,7 +214,7 @@ public class MediaFile {
addFileType("PNG", FILE_TYPE_PNG, "image/png", MtpConstants.FORMAT_PNG);
addFileType("BMP", FILE_TYPE_BMP, "image/x-ms-bmp", MtpConstants.FORMAT_BMP);
addFileType("WBMP", FILE_TYPE_WBMP, "image/vnd.wap.wbmp");
- addFileType("WEBP", FILE_TYPE_WBMP, "image/webp");
+ addFileType("WEBP", FILE_TYPE_WEBP, "image/webp");
addFileType("M3U", FILE_TYPE_M3U, "audio/x-mpegurl", MtpConstants.FORMAT_M3U_PLAYLIST);
addFileType("M3U", FILE_TYPE_M3U, "application/x-mpegurl", MtpConstants.FORMAT_M3U_PLAYLIST);
diff --git a/media/java/android/media/MediaMetadataRetriever.java b/media/java/android/media/MediaMetadataRetriever.java
index 7ebedaf..10694c3 100644
--- a/media/java/android/media/MediaMetadataRetriever.java
+++ b/media/java/android/media/MediaMetadataRetriever.java
@@ -453,5 +453,10 @@ public class MediaMetadataRetriever
* @hide
*/
public static final int METADATA_KEY_TIMED_TEXT_LANGUAGES = 21;
+ /**
+ * If this key exists the media is drm-protected.
+ * @hide
+ */
+ public static final int METADATA_KEY_IS_DRM = 22;
// Add more here...
}
diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java
index 790eaa3..c55338a 100644
--- a/media/java/android/media/MediaScanner.java
+++ b/media/java/android/media/MediaScanner.java
@@ -422,6 +422,7 @@ public class MediaScanner
private long mFileSize;
private String mWriter;
private int mCompilation;
+ private boolean mIsDrm;
private boolean mNoMedia; // flag to suppress file from appearing in media tables
public FileCacheEntry beginFile(String path, String mimeType, long lastModified,
@@ -497,6 +498,7 @@ public class MediaScanner
mLastModified = lastModified;
mWriter = null;
mCompilation = 0;
+ mIsDrm = false;
return entry;
}
@@ -599,6 +601,8 @@ public class MediaScanner
mWriter = value.trim();
} else if (name.equalsIgnoreCase("compilation")) {
mCompilation = parseSubstring(value, 0, 0);
+ } else if (name.equalsIgnoreCase("isdrm")) {
+ mIsDrm = (parseSubstring(value, 0, 0) == 1);
}
}
@@ -671,6 +675,7 @@ public class MediaScanner
map.put(MediaStore.MediaColumns.DATE_MODIFIED, mLastModified);
map.put(MediaStore.MediaColumns.SIZE, mFileSize);
map.put(MediaStore.MediaColumns.MIME_TYPE, mMimeType);
+ map.put(MediaStore.MediaColumns.IS_DRM, mIsDrm);
if (!mNoMedia) {
if (MediaFile.isVideoFileType(mFileType)) {
diff --git a/media/java/android/media/RingtoneManager.java b/media/java/android/media/RingtoneManager.java
index 8481410..9c0819f 100644
--- a/media/java/android/media/RingtoneManager.java
+++ b/media/java/android/media/RingtoneManager.java
@@ -487,7 +487,7 @@ public class RingtoneManager {
private Cursor getInternalRingtones() {
return query(
MediaStore.Audio.Media.INTERNAL_CONTENT_URI, INTERNAL_COLUMNS,
- constructBooleanTrueWhereClause(mFilterColumns),
+ constructBooleanTrueWhereClause(mFilterColumns, mIncludeDrm),
null, MediaStore.Audio.Media.DEFAULT_SORT_ORDER);
}
@@ -506,7 +506,7 @@ public class RingtoneManager {
status.equals(Environment.MEDIA_MOUNTED_READ_ONLY))
? query(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, MEDIA_COLUMNS,
- constructBooleanTrueWhereClause(mFilterColumns), null,
+ constructBooleanTrueWhereClause(mFilterColumns, mIncludeDrm), null,
MediaStore.Audio.Media.DEFAULT_SORT_ORDER)
: null;
}
@@ -536,11 +536,13 @@ public class RingtoneManager {
* @param columns The columns that must be true.
* @return The where clause.
*/
- private static String constructBooleanTrueWhereClause(List<String> columns) {
+ private static String constructBooleanTrueWhereClause(List<String> columns, boolean includeDrm) {
if (columns == null) return null;
StringBuilder sb = new StringBuilder();
+ sb.append("(");
+
for (int i = columns.size() - 1; i >= 0; i--) {
sb.append(columns.get(i)).append("=1 or ");
}
@@ -549,7 +551,18 @@ public class RingtoneManager {
// Remove last ' or '
sb.setLength(sb.length() - 4);
}
-
+
+ sb.append(")");
+
+ if (!includeDrm) {
+ // If not DRM files should be shown, the where clause
+ // will be something like "(is_notification=1) and is_drm=0"
+ sb.append(" and ");
+ sb.append(MediaStore.MediaColumns.IS_DRM);
+ sb.append("=0");
+ }
+
+
return sb.toString();
}
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp
index 5582f92..73a05a5 100644
--- a/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/MPEG4Extractor.cpp
@@ -387,10 +387,6 @@ status_t MPEG4Extractor::readMetaData() {
return mInitCheck;
}
-void MPEG4Extractor::setDrmFlag(bool flag) {
- mIsDrm = flag;
-}
-
char* MPEG4Extractor::getDrmTrackInfo(size_t trackID, int *len) {
if (mFirstSINF == NULL) {
return NULL;
diff --git a/media/libstagefright/MediaExtractor.cpp b/media/libstagefright/MediaExtractor.cpp
index af0131e..a8023df 100644
--- a/media/libstagefright/MediaExtractor.cpp
+++ b/media/libstagefright/MediaExtractor.cpp
@@ -116,8 +116,13 @@ sp<MediaExtractor> MediaExtractor::Create(
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC_ADTS)) {
ret = new AACExtractor(source);
}
- if (ret != NULL && isDrm) {
- ret->getMetaData()->setInt32(kKeyIsDRM, 1);
+
+ if (ret != NULL) {
+ if (isDrm) {
+ ret->setDrmFlag(true);
+ } else {
+ ret->setDrmFlag(false);
+ }
}
return ret;
diff --git a/media/libstagefright/StagefrightMediaScanner.cpp b/media/libstagefright/StagefrightMediaScanner.cpp
index f82ff32..89faff7 100644
--- a/media/libstagefright/StagefrightMediaScanner.cpp
+++ b/media/libstagefright/StagefrightMediaScanner.cpp
@@ -158,6 +158,7 @@ status_t StagefrightMediaScanner::processFile(
{ "duration", METADATA_KEY_DURATION },
{ "writer", METADATA_KEY_WRITER },
{ "compilation", METADATA_KEY_COMPILATION },
+ { "isdrm", METADATA_KEY_IS_DRM },
};
static const size_t kNumEntries = sizeof(kKeyMap) / sizeof(kKeyMap[0]);
diff --git a/media/libstagefright/StagefrightMetadataRetriever.cpp b/media/libstagefright/StagefrightMetadataRetriever.cpp
index de3957b..778c0b5 100644
--- a/media/libstagefright/StagefrightMetadataRetriever.cpp
+++ b/media/libstagefright/StagefrightMetadataRetriever.cpp
@@ -530,6 +530,11 @@ void StagefrightMetadataRetriever::parseMetaData() {
}
}
}
+
+ // To check whether the media file is drm-protected
+ if (mExtractor->getDrmFlag()) {
+ mMetaData.add(METADATA_KEY_IS_DRM, String8("1"));
+ }
}
} // namespace android
diff --git a/media/libstagefright/include/MPEG4Extractor.h b/media/libstagefright/include/MPEG4Extractor.h
index 3bd4c7e..eae62c6 100644
--- a/media/libstagefright/include/MPEG4Extractor.h
+++ b/media/libstagefright/include/MPEG4Extractor.h
@@ -40,7 +40,6 @@ public:
virtual sp<MetaData> getMetaData();
// for DRM
- virtual void setDrmFlag(bool flag);
virtual char* getDrmTrackInfo(size_t trackID, int *len);
protected:
diff --git a/packages/SettingsProvider/AndroidManifest.xml b/packages/SettingsProvider/AndroidManifest.xml
index e5f52e2..dd0d064 100644
--- a/packages/SettingsProvider/AndroidManifest.xml
+++ b/packages/SettingsProvider/AndroidManifest.xml
@@ -6,7 +6,6 @@
android:label="@string/app_label"
android:process="system"
android:backupAgent="SettingsBackupAgent"
- android:fullBackupAgent="SettingsBackupAgent"
android:killAfterRestore="false"
android:icon="@drawable/ic_launcher_settings">
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
index 9469601..3a7a6e1 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
@@ -36,7 +36,7 @@ import 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 258059c..39c36f1 100644
--- a/packages/SharedStorageBackup/AndroidManifest.xml
+++ b/packages/SharedStorageBackup/AndroidManifest.xml
@@ -23,7 +23,7 @@
<application android:allowClearUserData="false"
android:permission="android.permission.CONFIRM_FULL_BACKUP"
- android:fullBackupAgent=".SharedStorageAgent"
+ android:backupAgent=".SharedStorageAgent"
android:allowBackup="false" >
</application>
</manifest>
diff --git a/packages/SharedStorageBackup/src/com/android/sharedstoragebackup/SharedStorageAgent.java b/packages/SharedStorageBackup/src/com/android/sharedstoragebackup/SharedStorageAgent.java
index b02ca2e..6c677b8 100644
--- a/packages/SharedStorageBackup/src/com/android/sharedstoragebackup/SharedStorageAgent.java
+++ b/packages/SharedStorageBackup/src/com/android/sharedstoragebackup/SharedStorageAgent.java
@@ -1,9 +1,10 @@
package com.android.sharedstoragebackup;
-import android.app.backup.FullBackup;
import android.app.backup.FullBackupAgent;
+import android.app.backup.FullBackup;
import android.app.backup.BackupDataInput;
import android.app.backup.BackupDataOutput;
+import android.app.backup.FullBackupDataOutput;
import android.content.Context;
import android.os.Environment;
import android.os.ParcelFileDescriptor;
@@ -30,9 +31,11 @@ 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/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index f42cbbf..26ea225 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -30,10 +30,6 @@
<service android:name=".screenshot.TakeScreenshotService"
android:exported="false" />
- <activity android:name=".usb.UsbPreferenceActivity"
- android:theme="@*android:style/Theme.Holo.Dialog.Alert"
- android:excludeFromRecents="true">
- </activity>
<activity android:name=".usb.UsbStorageActivity"
android:excludeFromRecents="true">
</activity>
diff --git a/packages/SystemUI/res/layout/usb_preference_buttons.xml b/packages/SystemUI/res/layout/usb_preference_buttons.xml
deleted file mode 100644
index babe07e..0000000
--- a/packages/SystemUI/res/layout/usb_preference_buttons.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<!-- Check box that is displayed in the activity resolver UI for the user
- to make their selection the preferred activity. -->
-<LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingLeft="14dip"
- android:paddingRight="15dip"
- android:orientation="vertical">
-
- <Button
- android:id="@+id/mtp_ptp_button"
- android:text="@string/use_ptp_button_title"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:focusable="true"
- android:clickable="true" />
-
- <Button
- android:id="@+id/installer_cd_button"
- android:text="@string/installer_cd_button_title"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:focusable="true"
- android:clickable="true" />
-
-</LinearLayout>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 70f9b75..882455e 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -157,15 +157,6 @@
<!-- Compatibility mode help screen: body text. [CHAR LIMIT=150] -->
<string name="compat_mode_help_body">When an app was designed for a smaller screen, a zoom control will appear by the clock.</string>
- <!-- Title for the USB function chooser in UsbPreferenceActivity. [CHAR LIMIT=30] -->
- <string name="usb_preference_title">USB file transfer options</string>
- <!-- Label for the MTP USB function in UsbPreferenceActivity. [CHAR LIMIT=50] -->
- <string name="use_mtp_button_title">Mount as a media player (MTP)</string>
- <!-- Label for the PTP USB function in UsbPreferenceActivity. [CHAR LIMIT=50] -->
- <string name="use_ptp_button_title">Mount as a camera (PTP)</string>
- <!-- Label for the installer CD image option in UsbPreferenceActivity. [CHAR LIMIT=50] -->
- <string name="installer_cd_button_title">Install Android File Transfer application for Mac</string>
-
<!-- toast message displayed when a screenshot is saved to the Gallery. -->
<string name="screenshot_saving_toast">Screenshot saved to Gallery</string>
<!-- toast message displayed when we fail to take a screenshot. -->
diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbPreferenceActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbPreferenceActivity.java
deleted file mode 100644
index 60906a1..0000000
--- a/packages/SystemUI/src/com/android/systemui/usb/UsbPreferenceActivity.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.usb;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.hardware.usb.UsbManager;
-import android.os.Bundle;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.util.Log;
-import android.widget.Button;
-
-import java.io.File;
-
-import com.android.systemui.R;
-
-public class UsbPreferenceActivity extends Activity implements View.OnClickListener {
-
- private static final String TAG = "UsbPreferenceActivity";
-
- private UsbManager mUsbManager;
- private String mCurrentFunction;
- private String[] mFunctions;
- private String mInstallerImagePath;
- private AlertDialog mDialog;
- private Button mMtpPtpButton;
- private Button mInstallerCdButton;
- private boolean mPtpActive;
-
- @Override
- public void onCreate(Bundle icicle) {
- super.onCreate(icicle);
-
- mUsbManager = (UsbManager)getSystemService(Context.USB_SERVICE);
-
- AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this);
- dialogBuilder.setTitle(getString(R.string.usb_preference_title));
-
- LayoutInflater inflater = (LayoutInflater)getSystemService(
- Context.LAYOUT_INFLATER_SERVICE);
- View buttonView = inflater.inflate(R.layout.usb_preference_buttons, null);
- dialogBuilder.setView(buttonView);
- mMtpPtpButton = (Button)buttonView.findViewById(R.id.mtp_ptp_button);
- mInstallerCdButton = (Button)buttonView.findViewById(R.id.installer_cd_button);
- mMtpPtpButton.setOnClickListener(this);
- mInstallerCdButton.setOnClickListener(this);
-
- mPtpActive = mUsbManager.isFunctionEnabled(UsbManager.USB_FUNCTION_PTP);
- if (mPtpActive) {
- mMtpPtpButton.setText(R.string.use_mtp_button_title);
- }
-
- mInstallerImagePath = getString(com.android.internal.R.string.config_isoImagePath);
- if (!(new File(mInstallerImagePath)).exists()) {
- mInstallerCdButton.setVisibility(View.GONE);
- }
-
- mDialog = dialogBuilder.show();
- }
-
- public void onClick(View v) {
- if (v.equals(mMtpPtpButton)) {
- if (mPtpActive) {
- mUsbManager.setCurrentFunction(UsbManager.USB_FUNCTION_MTP, true);
- } else {
- mUsbManager.setCurrentFunction(UsbManager.USB_FUNCTION_PTP, true);
- }
- } else if (v.equals(mInstallerCdButton)) {
- // installer CD is never default
- mUsbManager.setCurrentFunction(UsbManager.USB_FUNCTION_MASS_STORAGE, false);
- mUsbManager.setMassStorageBackingFile(mInstallerImagePath);
- }
-
- if (mDialog != null) {
- mDialog.dismiss();
- }
- finish();
- }
-}
diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java
index 3aa1239..6afccec 100644
--- a/services/java/com/android/server/BackupManagerService.java
+++ b/services/java/com/android/server/BackupManagerService.java
@@ -23,6 +23,7 @@ import android.app.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/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index afc04bb..b98d2a2 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -64,6 +64,7 @@ import android.util.EventLog;
import android.util.Slog;
import android.util.SparseIntArray;
+import com.android.internal.net.LegacyVpnInfo;
import com.android.internal.net.VpnConfig;
import com.android.internal.telephony.Phone;
import com.android.server.connectivity.Tethering;
@@ -2469,8 +2470,8 @@ public class ConnectivityService extends IConnectivityManager.Stub {
/**
* Protect a socket from VPN routing rules. This method is used by
- * VpnBuilder and not available in ConnectivityManager. Permission
- * checks are done in Vpn class.
+ * VpnBuilder and not available in ConnectivityManager. Permissions
+ * are checked in Vpn class.
* @hide
*/
@Override
@@ -2480,8 +2481,8 @@ public class ConnectivityService extends IConnectivityManager.Stub {
/**
* Prepare for a VPN application. This method is used by VpnDialogs
- * and not available in ConnectivityManager. Permission checks are
- * done in Vpn class.
+ * and not available in ConnectivityManager. Permissions are checked
+ * in Vpn class.
* @hide
*/
@Override
@@ -2492,8 +2493,8 @@ public class ConnectivityService extends IConnectivityManager.Stub {
/**
* Configure a TUN interface and return its file descriptor. Parameters
* are encoded and opaque to this class. This method is used by VpnBuilder
- * and not available in ConnectivityManager. Permission checks are done
- * in Vpn class.
+ * and not available in ConnectivityManager. Permissions are checked in
+ * Vpn class.
* @hide
*/
@Override
@@ -2502,12 +2503,25 @@ public class ConnectivityService extends IConnectivityManager.Stub {
}
/**
- * Handle a legacy VPN request.
+ * Start legacy VPN and return an intent to VpnDialogs. This method is
+ * used by VpnSettings and not available in ConnectivityManager.
+ * Permissions are checked in Vpn class.
+ * @hide
+ */
+ @Override
+ public void startLegacyVpn(VpnConfig config, String[] racoon, String[] mtpd) {
+ mVpn.startLegacyVpn(config, racoon, mtpd);
+ }
+
+ /**
+ * Return the information of the ongoing legacy VPN. This method is used
+ * by VpnSettings and not available in ConnectivityManager. Permissions
+ * are checked in Vpn class.
* @hide
*/
@Override
- public void doLegacyVpn(VpnConfig config, String[] racoon, String[] mtpd) {
- mVpn.doLegacyVpn(config, racoon, mtpd);
+ public LegacyVpnInfo getLegacyVpnInfo() {
+ return mVpn.getLegacyVpnInfo();
}
private String getDefaultInterface() {
diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java
index 14abf80..2d55433 100644
--- a/services/java/com/android/server/InputMethodManagerService.java
+++ b/services/java/com/android/server/InputMethodManagerService.java
@@ -1623,8 +1623,11 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
if (lastImi == null) return null;
try {
final int lastSubtypeHash = Integer.valueOf(lastIme.second);
- return lastImi.getSubtypeAt(getSubtypeIdFromHashCode(
- lastImi, lastSubtypeHash));
+ final int lastSubtypeId = getSubtypeIdFromHashCode(lastImi, lastSubtypeHash);
+ if (lastSubtypeId < 0 || lastSubtypeId >= lastImi.getSubtypeCount()) {
+ return null;
+ }
+ return lastImi.getSubtypeAt(lastSubtypeId);
} catch (NumberFormatException e) {
return null;
}
diff --git a/services/java/com/android/server/SystemBackupAgent.java b/services/java/com/android/server/SystemBackupAgent.java
index 08c6699..950f3b6 100644
--- a/services/java/com/android/server/SystemBackupAgent.java
+++ b/services/java/com/android/server/SystemBackupAgent.java
@@ -138,7 +138,7 @@ 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 7725891..5f0922e 100644
--- a/services/java/com/android/server/WifiService.java
+++ b/services/java/com/android/server/WifiService.java
@@ -36,6 +36,7 @@ import android.net.wifi.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 10dd924..80cdf6b 100644
--- a/services/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -436,7 +436,8 @@ public 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 48b0b66..29cccb6 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -1953,6 +1953,9 @@ 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/connectivity/Vpn.java b/services/java/com/android/server/connectivity/Vpn.java
index bb3ce28..c185012 100644
--- a/services/java/com/android/server/connectivity/Vpn.java
+++ b/services/java/com/android/server/connectivity/Vpn.java
@@ -37,6 +37,7 @@ import android.os.SystemProperties;
import android.util.Log;
import com.android.internal.R;
+import com.android.internal.net.LegacyVpnInfo;
import com.android.internal.net.VpnConfig;
import com.android.server.ConnectivityService.VpnCallback;
@@ -250,6 +251,7 @@ public class Vpn extends INetworkManagementEventObserver.Stub {
mContext.getString(R.string.vpn_title_long, label);
String text = (config.session == null) ? mContext.getString(R.string.vpn_text) :
mContext.getString(R.string.vpn_text_long, config.session);
+ config.startTime = SystemClock.elapsedRealtime();
long identity = Binder.clearCallingIdentity();
Notification notification = new Notification.Builder(mContext)
@@ -257,7 +259,7 @@ public class Vpn extends INetworkManagementEventObserver.Stub {
.setLargeIcon(icon)
.setContentTitle(title)
.setContentText(text)
- .setContentIntent(VpnConfig.getIntentForNotification(mContext, config))
+ .setContentIntent(VpnConfig.getIntentForStatusPanel(mContext, config))
.setDefaults(Notification.DEFAULT_ALL)
.setOngoing(true)
.getNotification();
@@ -284,24 +286,35 @@ public class Vpn extends INetworkManagementEventObserver.Stub {
private native void jniProtect(int socket, String interfaze);
/**
- * Handle a legacy VPN request. This method stops the daemons and restart
- * them if arguments are not null. Heavy things are offloaded to another
+ * Start legacy VPN. This method stops the daemons and restart them
+ * if arguments are not null. Heavy things are offloaded to another
* thread, so callers will not be blocked for a long time.
*
* @param config The parameters to configure the network.
* @param raoocn The arguments to be passed to racoon.
* @param mtpd The arguments to be passed to mtpd.
*/
- public synchronized void doLegacyVpn(VpnConfig config, String[] racoon, String[] mtpd) {
+ public synchronized void startLegacyVpn(VpnConfig config, String[] racoon, String[] mtpd) {
// Prepare for the new request. This also checks the caller.
prepare(null, VpnConfig.LEGACY_VPN);
- // Start a new runner and we are done!
+ // Start a new LegacyVpnRunner and we are done!
mLegacyVpnRunner = new LegacyVpnRunner(config, racoon, mtpd);
mLegacyVpnRunner.start();
}
/**
+ * Return the information of the current ongoing legacy VPN.
+ */
+ public synchronized LegacyVpnInfo getLegacyVpnInfo() {
+ // Only system user can call this method.
+ if (Binder.getCallingUid() != Process.SYSTEM_UID) {
+ throw new SecurityException("Unauthorized Caller");
+ }
+ return (mLegacyVpnRunner == null) ? null : mLegacyVpnRunner.getInfo();
+ }
+
+ /**
* Bringing up a VPN connection takes time, and that is all this thread
* does. Here we have plenty of time. The only thing we need to take
* care of is responding to interruptions as soon as possible. Otherwise
@@ -315,6 +328,8 @@ public class Vpn extends INetworkManagementEventObserver.Stub {
private final VpnConfig mConfig;
private final String[] mDaemons;
private final String[][] mArguments;
+ private final LegacyVpnInfo mInfo;
+
private long mTimer = -1;
public LegacyVpnRunner(VpnConfig config, String[] racoon, String[] mtpd) {
@@ -322,7 +337,10 @@ public class Vpn extends INetworkManagementEventObserver.Stub {
mConfig = config;
mDaemons = new String[] {"racoon", "mtpd"};
mArguments = new String[][] {racoon, mtpd};
+ mInfo = new LegacyVpnInfo();
+ // Legacy VPN is not a real package, so we use it to carry the key.
+ mInfo.key = mConfig.packagz;
mConfig.packagz = VpnConfig.LEGACY_VPN;
}
@@ -334,14 +352,22 @@ public class Vpn extends INetworkManagementEventObserver.Stub {
interrupt();
}
+ public LegacyVpnInfo getInfo() {
+ // Update the info when VPN is disconnected.
+ if (mInfo.state == LegacyVpnInfo.STATE_CONNECTED && mInterface == null) {
+ mInfo.state = LegacyVpnInfo.STATE_DISCONNECTED;
+ mInfo.intent = null;
+ }
+ return mInfo;
+ }
+
@Override
public void run() {
// Wait for the previous thread since it has been interrupted.
- Log.v(TAG, "wait");
+ Log.v(TAG, "Waiting");
synchronized (TAG) {
- Log.v(TAG, "begin");
+ Log.v(TAG, "Executing");
execute();
- Log.v(TAG, "end");
}
}
@@ -353,7 +379,8 @@ public class Vpn extends INetworkManagementEventObserver.Stub {
} else if (now - mTimer <= 30000) {
Thread.sleep(yield ? 200 : 1);
} else {
- throw new InterruptedException("time is up");
+ mInfo.state = LegacyVpnInfo.STATE_TIMEOUT;
+ throw new IllegalStateException("time is up");
}
}
@@ -362,6 +389,7 @@ public class Vpn extends INetworkManagementEventObserver.Stub {
try {
// Initialize the timer.
checkpoint(false);
+ mInfo.state = LegacyVpnInfo.STATE_INITIALIZING;
// First stop the daemons.
for (String daemon : mDaemons) {
@@ -390,8 +418,10 @@ public class Vpn extends INetworkManagementEventObserver.Stub {
restart = restart || (arguments != null);
}
if (!restart) {
+ mInfo.state = LegacyVpnInfo.STATE_DISCONNECTED;
return;
}
+ mInfo.state = LegacyVpnInfo.STATE_CONNECTING;
// Start the daemon with arguments.
for (int i = 0; i < mDaemons.length; ++i) {
@@ -459,7 +489,7 @@ public class Vpn extends INetworkManagementEventObserver.Stub {
String daemon = mDaemons[i];
if (mArguments[i] != null && !"running".equals(
SystemProperties.get("init.svc." + daemon))) {
- throw new IllegalArgumentException(daemon + " is dead");
+ throw new IllegalStateException(daemon + " is dead");
}
}
checkpoint(true);
@@ -492,11 +522,20 @@ public class Vpn extends INetworkManagementEventObserver.Stub {
mInterface = mConfig.interfaze;
mCallback.override(mConfig.dnsServers, mConfig.searchDomains);
showNotification(mConfig, null, null);
+
+ Log.i(TAG, "Connected!");
+ mInfo.state = LegacyVpnInfo.STATE_CONNECTED;
+ mInfo.intent = VpnConfig.getIntentForStatusPanel(mContext, null);
}
- Log.i(TAG, "Connected!");
} catch (Exception e) {
- Log.i(TAG, "Abort because " + e.getMessage());
+ Log.i(TAG, "Aborting", e);
exit();
+ } finally {
+ // Do not leave an unstable state.
+ if (mInfo.state == LegacyVpnInfo.STATE_INITIALIZING ||
+ mInfo.state == LegacyVpnInfo.STATE_CONNECTING) {
+ mInfo.state = LegacyVpnInfo.STATE_FAILED;
+ }
}
}
}
diff --git a/services/java/com/android/server/usb/UsbDeviceManager.java b/services/java/com/android/server/usb/UsbDeviceManager.java
index 13a76b3..d645160 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) {
@@ -530,11 +556,12 @@ public class UsbDeviceManager {
notification.sound = null;
notification.vibrate = null;
- Intent intent = new Intent();
+ Intent intent = new Intent(
+ Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
- intent.setClassName("com.android.systemui",
- "com.android.systemui.usb.UsbPreferenceActivity");
+ intent.setComponent(new ComponentName("com.android.settings",
+ "com.android.settings.UsbSettings"));
PendingIntent pi = PendingIntent.getActivity(mContext, 0,
intent, 0);
notification.setLatestEventInfo(mContext, title, message, pi);
diff --git a/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp
index a774841..33125c4 100644
--- a/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp
+++ b/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp
@@ -103,6 +103,11 @@ void DisplayHardware::init(uint32_t dpy)
{
mNativeWindow = new FramebufferNativeWindow();
framebuffer_device_t const * fbDev = mNativeWindow->getDevice();
+ if (!fbDev) {
+ LOGE("Display subsystem failed to initialize. check logs. exiting...");
+ exit(0);
+ }
+
mDpiX = mNativeWindow->xdpi;
mDpiY = mNativeWindow->ydpi;
mRefreshRate = fbDev->fps;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 685613e..cccab4a 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -163,9 +163,34 @@ void SurfaceFlinger::bootFinished()
const nsecs_t duration = now - mBootTime;
LOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );
mBootFinished = true;
+
+ // wait patiently for the window manager death
+ const String16 name("window");
+ sp<IBinder> window(defaultServiceManager()->getService(name));
+ if (window != 0) {
+ window->linkToDeath(this);
+ }
+
+ // stop boot animation
property_set("ctl.stop", "bootanim");
}
+void SurfaceFlinger::binderDied(const wp<IBinder>& who)
+{
+ // the window manager died on us. prepare its eulogy.
+
+ // unfreeze the screen in case it was... frozen
+ mFreezeDisplayTime = 0;
+ mFreezeCount = 0;
+ mFreezeDisplay = false;
+
+ // reset screen orientation
+ setOrientation(0, eOrientationDefault, 0);
+
+ // restart the boot-animation
+ property_set("ctl.start", "bootanim");
+}
+
void SurfaceFlinger::onFirstRef()
{
run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY);
@@ -2470,11 +2495,14 @@ GraphicBufferAlloc::GraphicBufferAlloc() {}
GraphicBufferAlloc::~GraphicBufferAlloc() {}
sp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h,
- PixelFormat format, uint32_t usage) {
+ PixelFormat format, uint32_t usage, status_t* error) {
sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(w, h, format, usage));
status_t err = graphicBuffer->initCheck();
+ *error = err;
if (err != 0 || graphicBuffer->handle == 0) {
- GraphicBuffer::dumpAllocationsToSystemLog();
+ if (err == NO_MEMORY) {
+ GraphicBuffer::dumpAllocationsToSystemLog();
+ }
LOGE("GraphicBufferAlloc::createGraphicBuffer(w=%d, h=%d) "
"failed (%s), handle=%p",
w, h, strerror(-err), graphicBuffer->handle);
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index b49fa36..15661f0 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -96,7 +96,7 @@ public:
GraphicBufferAlloc();
virtual ~GraphicBufferAlloc();
virtual sp<GraphicBuffer> createGraphicBuffer(uint32_t w, uint32_t h,
- PixelFormat format, uint32_t usage);
+ PixelFormat format, uint32_t usage, status_t* error);
};
// ---------------------------------------------------------------------------
@@ -147,6 +147,7 @@ enum {
class SurfaceFlinger :
public BinderService<SurfaceFlinger>,
public BnSurfaceComposer,
+ public IBinder::DeathRecipient,
protected Thread
{
public:
@@ -193,6 +194,10 @@ public:
sp<Layer> getLayer(const sp<ISurface>& sur) const;
private:
+ // DeathRecipient interface
+ virtual void binderDied(const wp<IBinder>& who);
+
+private:
friend class Client;
friend class LayerBase;
friend class LayerBaseClient;
diff --git a/voip/java/com/android/server/sip/SipService.java b/voip/java/com/android/server/sip/SipService.java
index ddc8031..c553947 100644
--- a/voip/java/com/android/server/sip/SipService.java
+++ b/voip/java/com/android/server/sip/SipService.java
@@ -74,6 +74,7 @@ public final class SipService extends ISipService.Stub {
private static final int SHORT_EXPIRY_TIME = 10;
private static final int MIN_EXPIRY_TIME = 60;
private static final int DEFAULT_KEEPALIVE_INTERVAL = 10; // in seconds
+ private static final int DEFAULT_MAX_KEEPALIVE_INTERVAL = 120; // in seconds
private Context mContext;
private String mLocalIp;
@@ -101,6 +102,7 @@ public final class SipService extends ISipService.Stub {
private boolean mWifiEnabled;
private SipWakeLock mMyWakeLock;
private int mKeepAliveInterval;
+ private int mLastGoodKeepAliveInterval = DEFAULT_KEEPALIVE_INTERVAL;
/**
* Starts the SIP service. Do nothing if the SIP API is not supported on the
@@ -448,6 +450,7 @@ public final class SipService extends ISipService.Stub {
if (connected) {
mLocalIp = determineLocalIp();
mKeepAliveInterval = -1;
+ mLastGoodKeepAliveInterval = DEFAULT_KEEPALIVE_INTERVAL;
for (SipSessionGroupExt group : mSipGroups.values()) {
group.onConnectivityChanged(true);
}
@@ -471,7 +474,8 @@ public final class SipService extends ISipService.Stub {
private void startPortMappingLifetimeMeasurement(
SipProfile localProfile) {
- startPortMappingLifetimeMeasurement(localProfile, -1);
+ startPortMappingLifetimeMeasurement(localProfile,
+ DEFAULT_MAX_KEEPALIVE_INTERVAL);
}
private void startPortMappingLifetimeMeasurement(
@@ -482,8 +486,16 @@ public final class SipService extends ISipService.Stub {
Log.d(TAG, "start NAT port mapping timeout measurement on "
+ localProfile.getUriString());
- mIntervalMeasurementProcess =
- new IntervalMeasurementProcess(localProfile, maxInterval);
+ int minInterval = mLastGoodKeepAliveInterval;
+ if (minInterval >= maxInterval) {
+ // If mLastGoodKeepAliveInterval also does not work, reset it
+ // to the default min
+ minInterval = mLastGoodKeepAliveInterval
+ = DEFAULT_KEEPALIVE_INTERVAL;
+ Log.d(TAG, " reset min interval to " + minInterval);
+ }
+ mIntervalMeasurementProcess = new IntervalMeasurementProcess(
+ localProfile, minInterval, maxInterval);
mIntervalMeasurementProcess.start();
}
}
@@ -539,7 +551,7 @@ public final class SipService extends ISipService.Stub {
private int getKeepAliveInterval() {
return (mKeepAliveInterval < 0)
- ? DEFAULT_KEEPALIVE_INTERVAL
+ ? mLastGoodKeepAliveInterval
: mKeepAliveInterval;
}
@@ -768,27 +780,33 @@ public final class SipService extends ISipService.Stub {
private class IntervalMeasurementProcess implements Runnable,
SipSessionGroup.KeepAliveProcessCallback {
private static final String TAG = "SipKeepAliveInterval";
- private static final int MAX_INTERVAL = 120; // in seconds
private static final int MIN_INTERVAL = 5; // in seconds
private static final int PASS_THRESHOLD = 10;
private static final int MAX_RETRY_COUNT = 5;
private static final int NAT_MEASUREMENT_RETRY_INTERVAL = 120; // in seconds
private SipSessionGroupExt mGroup;
private SipSessionGroup.SipSessionImpl mSession;
- private int mMinInterval = DEFAULT_KEEPALIVE_INTERVAL; // in seconds
+ private int mMinInterval;
private int mMaxInterval;
private int mInterval;
private int mPassCount = 0;
- public IntervalMeasurementProcess(SipProfile localProfile, int maxInterval) {
- mMaxInterval = (maxInterval < 0) ? MAX_INTERVAL : maxInterval;
- mInterval = (mMaxInterval + mMinInterval) / 2;
+ public IntervalMeasurementProcess(SipProfile localProfile,
+ int minInterval, int maxInterval) {
+ mMaxInterval = maxInterval;
+ mMinInterval = minInterval;
+ mInterval = (maxInterval + minInterval) / 2;
// Don't start measurement if the interval is too small
- if (mInterval < MIN_INTERVAL) {
+ if (mInterval < DEFAULT_KEEPALIVE_INTERVAL) {
Log.w(TAG, "interval is too small; measurement aborted; "
+ "maxInterval=" + mMaxInterval);
return;
+ } else if (checkTermination()) {
+ Log.w(TAG, "interval is too small; measurement aborted; "
+ + "interval=[" + mMinInterval + "," + mMaxInterval
+ + "]");
+ return;
}
try {
@@ -842,6 +860,10 @@ public final class SipService extends ISipService.Stub {
}
}
+ private boolean checkTermination() {
+ return ((mMaxInterval - mMinInterval) < MIN_INTERVAL);
+ }
+
// SipSessionGroup.KeepAliveProcessCallback
@Override
public void onResponse(boolean portChanged) {
@@ -850,6 +872,9 @@ public final class SipService extends ISipService.Stub {
if (++mPassCount != PASS_THRESHOLD) return;
// update the interval, since the current interval is good to
// keep the port mapping.
+ if (mKeepAliveInterval > 0) {
+ mLastGoodKeepAliveInterval = mKeepAliveInterval;
+ }
mKeepAliveInterval = mMinInterval = mInterval;
if (DEBUG) {
Log.d(TAG, "measured good keepalive interval: "
@@ -860,9 +885,13 @@ public final class SipService extends ISipService.Stub {
// Since the rport is changed, shorten the interval.
mMaxInterval = mInterval;
}
- if ((mMaxInterval - mMinInterval) < MIN_INTERVAL) {
+ if (checkTermination()) {
// update mKeepAliveInterval and stop measurement.
stop();
+ // If all the measurements failed, we still set it to
+ // mMinInterval; If mMinInterval still doesn't work, a new
+ // measurement with min interval=DEFAULT_KEEPALIVE_INTERVAL
+ // will be conducted.
mKeepAliveInterval = mMinInterval;
if (DEBUG) {
Log.d(TAG, "measured keepalive interval: "
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index 2a033d1..8c28319 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -2085,9 +2085,9 @@ public class WifiStateMachine extends StateMachine {
transitionTo(mDriverLoadedState);
sendMessageDelayed(CMD_START_SUPPLICANT, SUPPLICANT_RESTART_INTERVAL_MSECS);
} else {
- mSupplicantRestartCount = 0;
Log.e(TAG, "Failed " + mSupplicantRestartCount +
" times to start supplicant, unload driver");
+ mSupplicantRestartCount = 0;
transitionTo(mDriverLoadedState);
sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_STATE_UNKNOWN, 0));
}
diff --git a/services/java/com/android/server/WifiWatchdogService.java b/wifi/java/android/net/wifi/WifiWatchdogService.java
index 1356e2a..bce4b3a 100644
--- a/services/java/com/android/server/WifiWatchdogService.java
+++ b/wifi/java/android/net/wifi/WifiWatchdogService.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.server;
+package android.net.wifi;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
@@ -23,12 +23,9 @@ import android.content.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);