summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--AndroidManifest.xml20
-rw-r--r--WallpaperPicker/res/drawable-hdpi/tile_picker_focused.9.pngbin168 -> 0 bytes
-rw-r--r--WallpaperPicker/res/drawable-hdpi/tile_picker_pressed.9.pngbin144 -> 0 bytes
-rw-r--r--WallpaperPicker/res/drawable-hdpi/tile_picker_selected.9.pngbin165 -> 0 bytes
-rw-r--r--WallpaperPicker/res/drawable-mdpi/tile_picker_focused.9.pngbin165 -> 0 bytes
-rw-r--r--WallpaperPicker/res/drawable-mdpi/tile_picker_pressed.9.pngbin142 -> 0 bytes
-rw-r--r--WallpaperPicker/res/drawable-mdpi/tile_picker_selected.9.pngbin159 -> 0 bytes
-rw-r--r--WallpaperPicker/res/drawable-v21/ic_tick.xml31
-rw-r--r--WallpaperPicker/res/drawable-v21/wallpaper_tile_fg.xml39
-rw-r--r--WallpaperPicker/res/drawable-xhdpi/tile_picker_focused.9.pngbin174 -> 0 bytes
-rw-r--r--WallpaperPicker/res/drawable-xhdpi/tile_picker_pressed.9.pngbin147 -> 0 bytes
-rw-r--r--WallpaperPicker/res/drawable-xhdpi/tile_picker_selected.9.pngbin167 -> 0 bytes
-rw-r--r--WallpaperPicker/res/drawable-xxhdpi/tile_picker_focused.9.pngbin189 -> 0 bytes
-rw-r--r--WallpaperPicker/res/drawable-xxhdpi/tile_picker_pressed.9.pngbin154 -> 0 bytes
-rw-r--r--WallpaperPicker/res/drawable-xxhdpi/tile_picker_selected.9.pngbin175 -> 0 bytes
-rw-r--r--WallpaperPicker/res/drawable/wallpaper_tile_fg.xml32
-rw-r--r--WallpaperPicker/res/values-v19/styles.xml4
-rw-r--r--WallpaperPicker/res/values/styles.xml8
-rw-r--r--WallpaperPicker/src/com/android/launcher3/SavedWallpaperImages.java9
-rw-r--r--WallpaperPicker/src/com/android/launcher3/WallpaperCropActivity.java2
-rw-r--r--WallpaperPicker/src/com/android/launcher3/WallpaperPickerActivity.java10
-rw-r--r--proguard.flags5
-rw-r--r--protos/backup.proto24
-rw-r--r--res/drawable-hdpi/hand.pngbin16891 -> 0 bytes
-rw-r--r--res/drawable-hdpi/ic_home_search_normal_holo.pngbin1655 -> 0 bytes
-rw-r--r--res/drawable-hdpi/ic_home_voice_search_holo.pngbin1340 -> 0 bytes
-rw-r--r--res/drawable-hdpi/ic_pageindicator_current.pngbin1013 -> 1038 bytes
-rw-r--r--res/drawable-hdpi/ic_pageindicator_default.pngbin1046 -> 895 bytes
-rw-r--r--res/drawable-hdpi/search_frame.9.pngbin392 -> 0 bytes
-rw-r--r--res/drawable-hdpi/tab_selected_focused_holo.9.pngbin147 -> 0 bytes
-rw-r--r--res/drawable-hdpi/tab_selected_holo.9.pngbin148 -> 0 bytes
-rw-r--r--res/drawable-hdpi/tab_selected_pressed_focused_holo.9.pngbin231 -> 0 bytes
-rw-r--r--res/drawable-hdpi/tab_selected_pressed_holo.9.pngbin147 -> 0 bytes
-rw-r--r--res/drawable-hdpi/tab_unselected_focused_holo.9.pngbin146 -> 0 bytes
-rw-r--r--res/drawable-hdpi/tab_unselected_holo.9.pngbin153 -> 0 bytes
-rw-r--r--res/drawable-hdpi/tab_unselected_pressed_focused_holo.9.pngbin244 -> 0 bytes
-rw-r--r--res/drawable-hdpi/tab_unselected_pressed_holo.9.pngbin145 -> 0 bytes
-rw-r--r--res/drawable-land-hdpi/ic_home_voice_search_holo.pngbin1510 -> 0 bytes
-rw-r--r--res/drawable-land-mdpi/ic_home_voice_search_holo.pngbin959 -> 0 bytes
-rw-r--r--res/drawable-land-xhdpi/ic_home_voice_search_holo.pngbin2031 -> 0 bytes
-rw-r--r--res/drawable-land-xxhdpi/ic_home_voice_search_holo.pngbin3990 -> 0 bytes
-rw-r--r--res/drawable-mdpi/hand.pngbin9752 -> 0 bytes
-rw-r--r--res/drawable-mdpi/ic_home_search_normal_holo.pngbin1071 -> 0 bytes
-rw-r--r--res/drawable-mdpi/ic_home_voice_search_holo.pngbin865 -> 0 bytes
-rw-r--r--res/drawable-mdpi/ic_pageindicator_current.pngbin738 -> 704 bytes
-rw-r--r--res/drawable-mdpi/ic_pageindicator_default.pngbin746 -> 694 bytes
-rw-r--r--res/drawable-mdpi/search_frame.9.pngbin292 -> 0 bytes
-rw-r--r--res/drawable-mdpi/tab_selected_focused_holo.9.pngbin148 -> 0 bytes
-rw-r--r--res/drawable-mdpi/tab_selected_holo.9.pngbin151 -> 0 bytes
-rw-r--r--res/drawable-mdpi/tab_selected_pressed_focused_holo.9.pngbin199 -> 0 bytes
-rw-r--r--res/drawable-mdpi/tab_selected_pressed_holo.9.pngbin150 -> 0 bytes
-rw-r--r--res/drawable-mdpi/tab_unselected_focused_holo.9.pngbin150 -> 0 bytes
-rw-r--r--res/drawable-mdpi/tab_unselected_holo.9.pngbin157 -> 0 bytes
-rw-r--r--res/drawable-mdpi/tab_unselected_pressed_focused_holo.9.pngbin202 -> 0 bytes
-rw-r--r--res/drawable-mdpi/tab_unselected_pressed_holo.9.pngbin155 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/hand.pngbin26636 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/ic_home_search_normal_holo.pngbin2304 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/ic_home_voice_search_holo.pngbin1825 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/ic_pageindicator_current.pngbin1264 -> 1414 bytes
-rw-r--r--res/drawable-xhdpi/ic_pageindicator_default.pngbin1301 -> 1168 bytes
-rw-r--r--res/drawable-xhdpi/search_frame.9.pngbin521 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tab_selected_focused_holo.9.pngbin147 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tab_selected_holo.9.pngbin153 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tab_selected_pressed_focused_holo.9.pngbin210 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tab_selected_pressed_holo.9.pngbin147 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tab_unselected_focused_holo.9.pngbin148 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tab_unselected_holo.9.pngbin166 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tab_unselected_pressed_focused_holo.9.pngbin228 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tab_unselected_pressed_holo.9.pngbin149 -> 0 bytes
-rw-r--r--res/drawable-xxhdpi/hand.pngbin36124 -> 0 bytes
-rw-r--r--res/drawable-xxhdpi/ic_home_search_normal_holo.pngbin5046 -> 0 bytes
-rw-r--r--res/drawable-xxhdpi/ic_home_voice_search_holo.pngbin3774 -> 0 bytes
-rw-r--r--res/drawable-xxhdpi/ic_pageindicator_current.pngbin1865 -> 2105 bytes
-rw-r--r--res/drawable-xxhdpi/ic_pageindicator_default.pngbin1812 -> 1634 bytes
-rw-r--r--res/drawable-xxhdpi/search_bg_panel.9.pngbin1087 -> 0 bytes
-rw-r--r--res/drawable-xxhdpi/search_frame.9.pngbin1582 -> 0 bytes
-rw-r--r--res/drawable-xxhdpi/tab_selected_focused_holo.9.pngbin1033 -> 0 bytes
-rw-r--r--res/drawable-xxhdpi/tab_selected_holo.9.pngbin1030 -> 0 bytes
-rw-r--r--res/drawable-xxhdpi/tab_selected_pressed_holo.9.pngbin1033 -> 0 bytes
-rw-r--r--res/drawable-xxhdpi/tab_unselected_focused_holo.9.pngbin1035 -> 0 bytes
-rw-r--r--res/drawable-xxhdpi/tab_unselected_holo.9.pngbin1054 -> 0 bytes
-rw-r--r--res/drawable-xxhdpi/tab_unselected_pressed_holo.9.pngbin1035 -> 0 bytes
-rw-r--r--res/drawable/tab_widget_indicator_selector.xml33
-rw-r--r--res/layout-land/launcher.xml19
-rw-r--r--res/layout-land/longpress_cling.xml3
-rw-r--r--res/layout-land/migration_cling.xml2
-rw-r--r--res/layout-land/qsb.xml50
-rw-r--r--res/layout-port/launcher.xml28
-rw-r--r--res/layout-port/longpress_cling.xml3
-rw-r--r--res/layout-port/migration_cling.xml2
-rw-r--r--res/layout-port/qsb.xml72
-rw-r--r--res/layout-sw600dp-port/longpress_cling.xml3
-rw-r--r--res/layout-sw720dp/launcher.xml30
-rw-r--r--res/layout-sw720dp/market_button.xml36
-rw-r--r--res/layout-sw720dp/qsb.xml72
-rw-r--r--res/layout/apps_customize_pane.xml2
-rw-r--r--res/layout/apps_customize_widget.xml6
-rw-r--r--res/layout/drop_target_bar.xml39
-rw-r--r--res/layout/hotseat.xml2
-rw-r--r--res/layout/launcher_overlay.xml (renamed from res/layout/tab_widget_indicator.xml)7
-rw-r--r--res/layout/launcher_overlay_example.xml (renamed from res/layout-sw720dp/external_widget_drop_list_item.xml)40
-rw-r--r--res/layout/market_button.xml30
-rw-r--r--res/layout/overview_panel.xml42
-rw-r--r--res/layout/page_indicator.xml2
-rw-r--r--res/layout/page_indicator_marker.xml2
-rw-r--r--res/layout/search_drop_target_bar.xml45
-rw-r--r--res/layout/user_folder.xml3
-rw-r--r--res/layout/workspace_screen.xml2
-rw-r--r--res/mipmap-hdpi/ic_launcher_application.pngbin8430 -> 0 bytes
-rw-r--r--res/mipmap-mdpi/ic_launcher_application.pngbin4953 -> 0 bytes
-rw-r--r--res/mipmap-xhdpi/ic_launcher_application.pngbin11814 -> 0 bytes
-rw-r--r--res/mipmap-xxhdpi/ic_launcher_application.pngbin19388 -> 0 bytes
-rw-r--r--res/values-af-land/strings.xml25
-rw-r--r--res/values-af/strings.xml5
-rw-r--r--res/values-am-land/strings.xml25
-rw-r--r--res/values-am/strings.xml7
-rw-r--r--res/values-ar-land/strings.xml25
-rw-r--r--res/values-ar/strings.xml5
-rw-r--r--res/values-bg-land/strings.xml25
-rw-r--r--res/values-bg/strings.xml5
-rw-r--r--res/values-bn-rBD/strings.xml9
-rw-r--r--res/values-ca-land/strings.xml25
-rw-r--r--res/values-ca/strings.xml5
-rw-r--r--res/values-cs-land/strings.xml25
-rw-r--r--res/values-cs/strings.xml5
-rw-r--r--res/values-da-land/strings.xml25
-rw-r--r--res/values-da/strings.xml5
-rw-r--r--res/values-de-land/strings.xml25
-rw-r--r--res/values-de/strings.xml5
-rw-r--r--res/values-el-land/strings.xml25
-rw-r--r--res/values-el/strings.xml5
-rw-r--r--res/values-en-rGB-land/strings.xml25
-rw-r--r--res/values-en-rGB/strings.xml5
-rw-r--r--res/values-en-rIN/strings.xml5
-rw-r--r--res/values-es-land/strings.xml25
-rw-r--r--res/values-es-rUS-land/strings.xml25
-rw-r--r--res/values-es-rUS/strings.xml5
-rw-r--r--res/values-es/strings.xml5
-rw-r--r--res/values-et-rEE/strings.xml5
-rw-r--r--res/values-eu-rES/strings.xml11
-rw-r--r--res/values-fa-land/strings.xml25
-rw-r--r--res/values-fa/strings.xml5
-rw-r--r--res/values-fi-land/strings.xml25
-rw-r--r--res/values-fi/strings.xml5
-rw-r--r--res/values-fr-land/strings.xml25
-rw-r--r--res/values-fr-rCA/strings.xml5
-rw-r--r--res/values-fr/strings.xml5
-rw-r--r--res/values-gl-rES/strings.xml11
-rw-r--r--res/values-hi/strings.xml23
-rw-r--r--res/values-hr-land/strings.xml25
-rw-r--r--res/values-hr/strings.xml5
-rw-r--r--res/values-hu-land/strings.xml25
-rw-r--r--res/values-hu/strings.xml5
-rw-r--r--res/values-hy-rAM/strings.xml5
-rw-r--r--res/values-in-land/strings.xml25
-rw-r--r--res/values-in/strings.xml5
-rw-r--r--res/values-is-rIS/strings.xml9
-rw-r--r--res/values-it-land/strings.xml25
-rw-r--r--res/values-it/strings.xml5
-rw-r--r--res/values-iw-land/strings.xml25
-rw-r--r--res/values-iw/strings.xml5
-rw-r--r--res/values-ja-land/strings.xml25
-rw-r--r--res/values-ja/strings.xml5
-rw-r--r--res/values-ka-rGE/strings.xml5
-rw-r--r--res/values-kk-rKZ/strings.xml12
-rw-r--r--res/values-km-rKH/strings.xml7
-rw-r--r--res/values-kn-rIN/strings.xml9
-rw-r--r--res/values-ko-land/strings.xml25
-rw-r--r--res/values-ko/strings.xml5
-rw-r--r--res/values-ky-rKG/strings.xml12
-rw-r--r--res/values-land/strings.xml23
-rw-r--r--res/values-land/styles.xml24
-rw-r--r--res/values-lo-rLA/strings.xml9
-rw-r--r--res/values-lt-land/strings.xml25
-rw-r--r--res/values-lt/strings.xml5
-rw-r--r--res/values-lv-land/strings.xml25
-rw-r--r--res/values-lv/strings.xml5
-rw-r--r--res/values-mk-rMK/strings.xml11
-rw-r--r--res/values-ml-rIN/strings.xml9
-rw-r--r--res/values-mn-rMN/strings.xml5
-rw-r--r--res/values-mr-rIN/strings.xml9
-rw-r--r--res/values-ms-land/strings.xml25
-rw-r--r--res/values-ms-rMY/strings.xml5
-rw-r--r--res/values-my-rMM/strings.xml21
-rw-r--r--res/values-nb-land/strings.xml25
-rw-r--r--res/values-nb/strings.xml5
-rw-r--r--res/values-ne-rNP/strings.xml12
-rw-r--r--res/values-nl-land/strings.xml25
-rw-r--r--res/values-nl/strings.xml5
-rw-r--r--res/values-pl-land/strings.xml25
-rw-r--r--res/values-pl/strings.xml5
-rw-r--r--res/values-port/styles.xml25
-rw-r--r--res/values-pt-land/strings.xml25
-rw-r--r--res/values-pt-rPT-land/strings.xml25
-rw-r--r--res/values-pt-rPT/strings.xml5
-rw-r--r--res/values-pt/strings.xml47
-rw-r--r--res/values-rm-land/strings.xml25
-rw-r--r--res/values-ro-land/strings.xml25
-rw-r--r--res/values-ro/strings.xml5
-rw-r--r--res/values-ru-land/strings.xml25
-rw-r--r--res/values-ru/strings.xml5
-rw-r--r--res/values-si-rLK/strings.xml12
-rw-r--r--res/values-sk-land/strings.xml25
-rw-r--r--res/values-sk/strings.xml9
-rw-r--r--res/values-sl-land/strings.xml25
-rw-r--r--res/values-sl/strings.xml5
-rw-r--r--res/values-sr-land/strings.xml25
-rw-r--r--res/values-sr/strings.xml5
-rw-r--r--res/values-sv-land/strings.xml25
-rw-r--r--res/values-sv/strings.xml5
-rw-r--r--res/values-sw-land/strings.xml25
-rw-r--r--res/values-sw/strings.xml5
-rw-r--r--res/values-sw340dp-port/styles.xml5
-rw-r--r--res/values-sw340dp/dimens.xml8
-rw-r--r--res/values-sw720dp-port/styles.xml24
-rw-r--r--res/values-sw720dp/styles.xml25
-rw-r--r--res/values-ta-rIN/strings.xml33
-rw-r--r--res/values-te-rIN/strings.xml11
-rw-r--r--res/values-th-land/strings.xml25
-rw-r--r--res/values-th/strings.xml5
-rw-r--r--res/values-tl-land/strings.xml25
-rw-r--r--res/values-tl/strings.xml5
-rw-r--r--res/values-tr-land/strings.xml25
-rw-r--r--res/values-tr/strings.xml5
-rw-r--r--res/values-uk-land/strings.xml25
-rw-r--r--res/values-uk/strings.xml13
-rw-r--r--res/values-ur-rPK/strings.xml12
-rw-r--r--res/values-uz-rUZ/strings.xml12
-rw-r--r--res/values-v17/styles.xml3
-rw-r--r--res/values-vi-land/strings.xml25
-rw-r--r--res/values-vi/strings.xml5
-rw-r--r--res/values-zh-rCN-land/strings.xml25
-rw-r--r--res/values-zh-rCN/strings.xml5
-rw-r--r--res/values-zh-rHK/strings.xml9
-rw-r--r--res/values-zh-rTW-land/strings.xml25
-rw-r--r--res/values-zh-rTW/strings.xml5
-rw-r--r--res/values-zu-land/strings.xml25
-rw-r--r--res/values-zu/strings.xml5
-rw-r--r--res/values/attrs.xml20
-rw-r--r--res/values/colors.xml2
-rw-r--r--res/values/dimens.xml8
-rw-r--r--res/values/strings.xml17
-rw-r--r--res/values/styles.xml51
-rw-r--r--res/xml/default_workspace_4x4_no_all_apps.xml56
-rw-r--r--res/xml/default_workspace_5x5_no_all_apps.xml56
-rw-r--r--res/xml/default_workspace_5x6_no_all_apps.xml56
-rw-r--r--src/com/android/launcher3/AccessibleTabView.java51
-rw-r--r--src/com/android/launcher3/AllAppsList.java20
-rw-r--r--src/com/android/launcher3/AppInfo.java19
-rw-r--r--src/com/android/launcher3/AppsCustomizePagedView.java15
-rw-r--r--src/com/android/launcher3/AppsCustomizeTabHost.java26
-rw-r--r--src/com/android/launcher3/AutoInstallsLayout.java247
-rw-r--r--src/com/android/launcher3/BubbleTextView.java4
-rw-r--r--src/com/android/launcher3/DefaultLayoutParser.java290
-rw-r--r--src/com/android/launcher3/DeleteDropTarget.java8
-rw-r--r--src/com/android/launcher3/DeviceProfile.java80
-rw-r--r--src/com/android/launcher3/DragController.java17
-rw-r--r--src/com/android/launcher3/DragLayer.java90
-rw-r--r--src/com/android/launcher3/DrawableStateProxyView.java69
-rw-r--r--src/com/android/launcher3/DynamicGrid.java33
-rw-r--r--src/com/android/launcher3/FirstFrameAnimatorHelper.java8
-rw-r--r--src/com/android/launcher3/FocusHelper.java208
-rw-r--r--src/com/android/launcher3/FocusIndicatorView.java66
-rw-r--r--src/com/android/launcher3/HolographicImageView.java121
-rw-r--r--src/com/android/launcher3/HolographicLinearLayout.java134
-rw-r--r--src/com/android/launcher3/HolographicViewHelper.java109
-rw-r--r--src/com/android/launcher3/IconCache.java182
-rw-r--r--src/com/android/launcher3/InsettableFrameLayout.java96
-rw-r--r--src/com/android/launcher3/InstallShortcutReceiver.java396
-rw-r--r--src/com/android/launcher3/InstallWidgetReceiver.java190
-rw-r--r--src/com/android/launcher3/Launcher.java952
-rw-r--r--src/com/android/launcher3/LauncherAppState.java76
-rw-r--r--src/com/android/launcher3/LauncherBackupAgentHelper.java62
-rw-r--r--src/com/android/launcher3/LauncherBackupHelper.java750
-rw-r--r--src/com/android/launcher3/LauncherCallbacks.java108
-rw-r--r--src/com/android/launcher3/LauncherClings.java4
-rw-r--r--src/com/android/launcher3/LauncherExtension.java354
-rw-r--r--src/com/android/launcher3/LauncherFiles.java40
-rw-r--r--src/com/android/launcher3/LauncherModel.java582
-rw-r--r--src/com/android/launcher3/LauncherPreferencesBackupHelper.java44
-rw-r--r--src/com/android/launcher3/LauncherProvider.java746
-rw-r--r--src/com/android/launcher3/LauncherRootView.java17
-rw-r--r--src/com/android/launcher3/PagedView.java21
-rw-r--r--src/com/android/launcher3/PagedViewWidgetImageView.java2
-rw-r--r--src/com/android/launcher3/PagedViewWithDraggableItems.java4
-rw-r--r--src/com/android/launcher3/PendingAppWidgetHostView.java57
-rw-r--r--src/com/android/launcher3/SearchDropTargetBar.java58
-rw-r--r--src/com/android/launcher3/ShortcutInfo.java12
-rw-r--r--src/com/android/launcher3/Stats.java14
-rw-r--r--src/com/android/launcher3/Utilities.java133
-rw-r--r--src/com/android/launcher3/WidgetPreviewLoader.java37
-rw-r--r--src/com/android/launcher3/Workspace.java344
-rw-r--r--src/com/android/launcher3/compat/AppWidgetManagerCompatVL.java2
-rw-r--r--src/com/android/launcher3/compat/LauncherAppsCompat.java13
-rw-r--r--src/com/android/launcher3/compat/LauncherAppsCompatV16.java17
-rw-r--r--src/com/android/launcher3/compat/PackageInstallerCompatVL.java34
296 files changed, 3852 insertions, 5996 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 591d9b612..fb7ac3fab 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -88,7 +88,25 @@
android:stateNotNeeded="true"
android:theme="@style/Theme"
android:windowSoftInputMode="adjustPan"
- android:screenOrientation="nosensor">
+ android:screenOrientation="nosensor"
+ android:enabled="true">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.HOME" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <category android:name="android.intent.category.MONKEY"/>
+ </intent-filter>
+ </activity>
+
+ <activity
+ android:name="com.android.launcher3.LauncherExtension"
+ android:launchMode="singleTask"
+ android:clearTaskOnLaunch="true"
+ android:stateNotNeeded="true"
+ android:theme="@style/Theme"
+ android:windowSoftInputMode="adjustPan"
+ android:screenOrientation="nosensor"
+ android:enabled="false">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.HOME" />
diff --git a/WallpaperPicker/res/drawable-hdpi/tile_picker_focused.9.png b/WallpaperPicker/res/drawable-hdpi/tile_picker_focused.9.png
deleted file mode 100644
index c72d6a2c6..000000000
--- a/WallpaperPicker/res/drawable-hdpi/tile_picker_focused.9.png
+++ /dev/null
Binary files differ
diff --git a/WallpaperPicker/res/drawable-hdpi/tile_picker_pressed.9.png b/WallpaperPicker/res/drawable-hdpi/tile_picker_pressed.9.png
deleted file mode 100644
index 44c65ac3c..000000000
--- a/WallpaperPicker/res/drawable-hdpi/tile_picker_pressed.9.png
+++ /dev/null
Binary files differ
diff --git a/WallpaperPicker/res/drawable-hdpi/tile_picker_selected.9.png b/WallpaperPicker/res/drawable-hdpi/tile_picker_selected.9.png
deleted file mode 100644
index 461bacbcb..000000000
--- a/WallpaperPicker/res/drawable-hdpi/tile_picker_selected.9.png
+++ /dev/null
Binary files differ
diff --git a/WallpaperPicker/res/drawable-mdpi/tile_picker_focused.9.png b/WallpaperPicker/res/drawable-mdpi/tile_picker_focused.9.png
deleted file mode 100644
index 13b325b87..000000000
--- a/WallpaperPicker/res/drawable-mdpi/tile_picker_focused.9.png
+++ /dev/null
Binary files differ
diff --git a/WallpaperPicker/res/drawable-mdpi/tile_picker_pressed.9.png b/WallpaperPicker/res/drawable-mdpi/tile_picker_pressed.9.png
deleted file mode 100644
index 4e8196d36..000000000
--- a/WallpaperPicker/res/drawable-mdpi/tile_picker_pressed.9.png
+++ /dev/null
Binary files differ
diff --git a/WallpaperPicker/res/drawable-mdpi/tile_picker_selected.9.png b/WallpaperPicker/res/drawable-mdpi/tile_picker_selected.9.png
deleted file mode 100644
index eee69ec6d..000000000
--- a/WallpaperPicker/res/drawable-mdpi/tile_picker_selected.9.png
+++ /dev/null
Binary files differ
diff --git a/WallpaperPicker/res/drawable-v21/ic_tick.xml b/WallpaperPicker/res/drawable-v21/ic_tick.xml
new file mode 100644
index 000000000..5b270279d
--- /dev/null
+++ b/WallpaperPicker/res/drawable-v21/ic_tick.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 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.
+-->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:height="48dp"
+ android:viewportHeight="48"
+ android:viewportWidth="48"
+ android:width="48dp" >
+
+ <group>
+ <path
+ android:name="tick"
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M18 32.34l-8.34-8.34-2.83 2.83 11.17 11.17 24-24-2.83-2.83z" />
+ </group>
+
+</vector> \ No newline at end of file
diff --git a/WallpaperPicker/res/drawable-v21/wallpaper_tile_fg.xml b/WallpaperPicker/res/drawable-v21/wallpaper_tile_fg.xml
new file mode 100644
index 000000000..97cdcd637
--- /dev/null
+++ b/WallpaperPicker/res/drawable-v21/wallpaper_tile_fg.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 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.
+-->
+
+<ripple xmlns:android="http://schemas.android.com/apk/res/android"
+ android:color="#66FFFFFF" >
+
+ <item
+ android:id="@android:id/mask"
+ android:drawable="@android:color/white"/>
+ <item
+ android:bottom="23.25dp"
+ android:left="29.25dp"
+ android:right="29.25dp"
+ android:top="23.25dp">
+ <selector>
+ <item
+ android:drawable="@drawable/ic_tick"
+ android:state_selected="true"/>
+ <item
+ android:drawable="@drawable/ic_tick"
+ android:state_checked="true"/>
+ </selector>
+ </item>
+
+</ripple> \ No newline at end of file
diff --git a/WallpaperPicker/res/drawable-xhdpi/tile_picker_focused.9.png b/WallpaperPicker/res/drawable-xhdpi/tile_picker_focused.9.png
deleted file mode 100644
index 279e85963..000000000
--- a/WallpaperPicker/res/drawable-xhdpi/tile_picker_focused.9.png
+++ /dev/null
Binary files differ
diff --git a/WallpaperPicker/res/drawable-xhdpi/tile_picker_pressed.9.png b/WallpaperPicker/res/drawable-xhdpi/tile_picker_pressed.9.png
deleted file mode 100644
index abe0e0080..000000000
--- a/WallpaperPicker/res/drawable-xhdpi/tile_picker_pressed.9.png
+++ /dev/null
Binary files differ
diff --git a/WallpaperPicker/res/drawable-xhdpi/tile_picker_selected.9.png b/WallpaperPicker/res/drawable-xhdpi/tile_picker_selected.9.png
deleted file mode 100644
index b047591ac..000000000
--- a/WallpaperPicker/res/drawable-xhdpi/tile_picker_selected.9.png
+++ /dev/null
Binary files differ
diff --git a/WallpaperPicker/res/drawable-xxhdpi/tile_picker_focused.9.png b/WallpaperPicker/res/drawable-xxhdpi/tile_picker_focused.9.png
deleted file mode 100644
index 1004c14b8..000000000
--- a/WallpaperPicker/res/drawable-xxhdpi/tile_picker_focused.9.png
+++ /dev/null
Binary files differ
diff --git a/WallpaperPicker/res/drawable-xxhdpi/tile_picker_pressed.9.png b/WallpaperPicker/res/drawable-xxhdpi/tile_picker_pressed.9.png
deleted file mode 100644
index 9658444a1..000000000
--- a/WallpaperPicker/res/drawable-xxhdpi/tile_picker_pressed.9.png
+++ /dev/null
Binary files differ
diff --git a/WallpaperPicker/res/drawable-xxhdpi/tile_picker_selected.9.png b/WallpaperPicker/res/drawable-xxhdpi/tile_picker_selected.9.png
deleted file mode 100644
index a3cd30369..000000000
--- a/WallpaperPicker/res/drawable-xxhdpi/tile_picker_selected.9.png
+++ /dev/null
Binary files differ
diff --git a/WallpaperPicker/res/drawable/wallpaper_tile_fg.xml b/WallpaperPicker/res/drawable/wallpaper_tile_fg.xml
index c299f32c6..c66fa50ad 100644
--- a/WallpaperPicker/res/drawable/wallpaper_tile_fg.xml
+++ b/WallpaperPicker/res/drawable/wallpaper_tile_fg.xml
@@ -15,9 +15,33 @@
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_checked="true" android:drawable="@drawable/tile_picker_selected" />
- <item android:state_focused="true" android:drawable="@drawable/tile_picker_focused" />
- <item android:state_pressed="true" android:drawable="@drawable/tile_picker_pressed" />
- <item android:state_selected="true" android:drawable="@drawable/tile_picker_selected" />
+ <item android:state_checked="true" >
+ <shape>
+ <stroke
+ android:width="2dp"
+ android:color="#FFFFFFFF" />
+ <solid android:color="#33FFFFFF"/>
+ </shape>
+ </item>
+ <item android:state_focused="true" >
+ <shape>
+ <stroke
+ android:width="2dp"
+ android:color="#FFFFFFFF" />
+ </shape>
+ </item>
+ <item android:state_pressed="true">
+ <shape android:shape="rectangle">
+ <solid android:color="#33FFFFFF"/>
+ </shape>
+ </item>
+ <item android:state_selected="true" >
+ <shape>
+ <stroke
+ android:width="2dp"
+ android:color="#FFFFFFFF" />
+ <solid android:color="#33FFFFFF"/>
+ </shape>
+ </item>
<item android:drawable="@android:color/transparent" />
</selector>
diff --git a/WallpaperPicker/res/values-v19/styles.xml b/WallpaperPicker/res/values-v19/styles.xml
index 85a989d55..136cf012c 100644
--- a/WallpaperPicker/res/values-v19/styles.xml
+++ b/WallpaperPicker/res/values-v19/styles.xml
@@ -18,14 +18,14 @@
-->
<resources>
- <style name="Theme.WallpaperCropper" parent="@android:style/Theme.Holo">
+ <style name="Theme.WallpaperCropper" parent="@android:style/Theme.DeviceDefault">
<item name="android:actionBarStyle">@style/WallpaperCropperActionBar</item>
<item name="android:windowFullscreen">true</item>
<item name="android:windowActionBarOverlay">true</item>
<item name="android:windowTranslucentNavigation">true</item>
</style>
- <style name="Theme" parent="@android:style/Theme.Holo.Wallpaper.NoTitleBar">
+ <style name="Theme" parent="@android:style/Theme.DeviceDefault.Wallpaper.NoTitleBar">
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>
</style>
diff --git a/WallpaperPicker/res/values/styles.xml b/WallpaperPicker/res/values/styles.xml
index 16b11f279..f4008f159 100644
--- a/WallpaperPicker/res/values/styles.xml
+++ b/WallpaperPicker/res/values/styles.xml
@@ -18,7 +18,7 @@
-->
<resources>
- <style name="Theme.WallpaperCropper" parent="@android:style/Theme.Holo">
+ <style name="Theme.WallpaperCropper" parent="@android:style/Theme.DeviceDefault">
<item name="android:actionBarStyle">@style/WallpaperCropperActionBar</item>
<item name="android:windowFullscreen">true</item>
<item name="android:windowActionBarOverlay">true</item>
@@ -30,15 +30,15 @@
<item name="android:windowShowWallpaper">true</item>
</style>
- <style name="WallpaperCropperActionBar" parent="android:style/Widget.Holo.ActionBar">
+ <style name="WallpaperCropperActionBar" parent="@android:style/Widget.DeviceDefault.ActionBar">
<item name="android:displayOptions">showCustom</item>
<item name="android:background">#88000000</item>
</style>
- <style name="Theme" parent="@android:style/Theme.Holo.Wallpaper.NoTitleBar">
+ <style name="Theme" parent="@android:style/Theme.DeviceDefault.Wallpaper.NoTitleBar">
</style>
- <style name="ActionBarSetWallpaperStyle" parent="@android:style/Widget.Holo.ActionButton">
+ <style name="ActionBarSetWallpaperStyle" parent="@android:style/Widget.DeviceDefault.ActionButton">
<item name="android:textColor">#ffffffff</item>
</style>
</resources>
diff --git a/WallpaperPicker/src/com/android/launcher3/SavedWallpaperImages.java b/WallpaperPicker/src/com/android/launcher3/SavedWallpaperImages.java
index 2bdf8f1cd..9f92bc105 100644
--- a/WallpaperPicker/src/com/android/launcher3/SavedWallpaperImages.java
+++ b/WallpaperPicker/src/com/android/launcher3/SavedWallpaperImages.java
@@ -180,7 +180,6 @@ public class SavedWallpaperImages extends BaseAdapter implements ListAdapter {
static class ImageDb extends SQLiteOpenHelper {
final static int DB_VERSION = 1;
- final static String DB_NAME = "saved_wallpaper_images.db";
final static String TABLE_NAME = "saved_wallpaper_images";
final static String COLUMN_ID = "id";
final static String COLUMN_IMAGE_THUMBNAIL_FILENAME = "image_thumbnail";
@@ -189,7 +188,8 @@ public class SavedWallpaperImages extends BaseAdapter implements ListAdapter {
Context mContext;
public ImageDb(Context context) {
- super(context, context.getDatabasePath(DB_NAME).getPath(), null, DB_VERSION);
+ super(context, context.getDatabasePath(LauncherFiles.WALLPAPER_IMAGES_DB).getPath(),
+ null, DB_VERSION);
// Store the context for later use
mContext = context;
}
@@ -197,8 +197,9 @@ public class SavedWallpaperImages extends BaseAdapter implements ListAdapter {
public static void moveFromCacheDirectoryIfNecessary(Context context) {
// We used to store the saved images in the cache directory, but that meant they'd get
// deleted sometimes-- move them to the data directory
- File oldSavedImagesFile = new File(context.getCacheDir(), ImageDb.DB_NAME);
- File savedImagesFile = context.getDatabasePath(ImageDb.DB_NAME);
+ File oldSavedImagesFile = new File(context.getCacheDir(),
+ LauncherFiles.WALLPAPER_IMAGES_DB);
+ File savedImagesFile = context.getDatabasePath(LauncherFiles.WALLPAPER_IMAGES_DB);
if (oldSavedImagesFile.exists()) {
oldSavedImagesFile.renameTo(savedImagesFile);
}
diff --git a/WallpaperPicker/src/com/android/launcher3/WallpaperCropActivity.java b/WallpaperPicker/src/com/android/launcher3/WallpaperCropActivity.java
index d5c7cd93d..fa8ec64c2 100644
--- a/WallpaperPicker/src/com/android/launcher3/WallpaperCropActivity.java
+++ b/WallpaperPicker/src/com/android/launcher3/WallpaperCropActivity.java
@@ -202,7 +202,7 @@ public class WallpaperCropActivity extends Activity {
}
public static String getSharedPreferencesKey() {
- return WallpaperCropActivity.class.getName();
+ return LauncherFiles.WALLPAPER_CROP_PREFERENCES_KEY;
}
// As a ratio of screen height, the total distance we want the parallax effect to span
diff --git a/WallpaperPicker/src/com/android/launcher3/WallpaperPickerActivity.java b/WallpaperPicker/src/com/android/launcher3/WallpaperPickerActivity.java
index 07285372e..09e096396 100644
--- a/WallpaperPicker/src/com/android/launcher3/WallpaperPickerActivity.java
+++ b/WallpaperPicker/src/com/android/launcher3/WallpaperPickerActivity.java
@@ -86,8 +86,6 @@ public class WallpaperPickerActivity extends WallpaperCropActivity {
public static final int PICK_LIVE_WALLPAPER = 7;
private static final String TEMP_WALLPAPER_TILES = "TEMP_WALLPAPER_TILES";
private static final String SELECTED_INDEX = "SELECTED_INDEX";
- private static final String OLD_DEFAULT_WALLPAPER_THUMBNAIL_FILENAME = "default_thumb.jpg";
- private static final String DEFAULT_WALLPAPER_THUMBNAIL_FILENAME = "default_thumb2.jpg";
private static final int FLAG_POST_DELAY_MILLIS = 200;
private View mSelectedTile;
@@ -999,16 +997,16 @@ public class WallpaperPickerActivity extends WallpaperCropActivity {
private File getDefaultThumbFile() {
return new File(getFilesDir(), Build.VERSION.SDK_INT
- + "_" + DEFAULT_WALLPAPER_THUMBNAIL_FILENAME);
+ + "_" + LauncherFiles.DEFAULT_WALLPAPER_THUMBNAIL);
}
private boolean saveDefaultWallpaperThumb(Bitmap b) {
// Delete old thumbnails.
- new File(getFilesDir(), OLD_DEFAULT_WALLPAPER_THUMBNAIL_FILENAME).delete();
- new File(getFilesDir(), DEFAULT_WALLPAPER_THUMBNAIL_FILENAME).delete();
+ new File(getFilesDir(), LauncherFiles.DEFAULT_WALLPAPER_THUMBNAIL_OLD).delete();
+ new File(getFilesDir(), LauncherFiles.DEFAULT_WALLPAPER_THUMBNAIL).delete();
for (int i = Build.VERSION_CODES.JELLY_BEAN; i < Build.VERSION.SDK_INT; i++) {
- new File(getFilesDir(), i + "_" + DEFAULT_WALLPAPER_THUMBNAIL_FILENAME).delete();
+ new File(getFilesDir(), i + "_" + LauncherFiles.DEFAULT_WALLPAPER_THUMBNAIL).delete();
}
return writeImageToFileAsJpeg(getDefaultThumbFile(), b);
}
diff --git a/proguard.flags b/proguard.flags
index 0b28c0ef4..83a491dfd 100644
--- a/proguard.flags
+++ b/proguard.flags
@@ -57,3 +57,8 @@
public float getAnimationProgress();
public void setAnimationProgress(float);
}
+
+-keep class com.android.launcher3.FastBitmapDrawable {
+ public int getBrightness();
+ public void setBrightness(int);
+}
diff --git a/protos/backup.proto b/protos/backup.proto
index 7ba293702..8ae175234 100644
--- a/protos/backup.proto
+++ b/protos/backup.proto
@@ -37,12 +37,36 @@ message CheckedMessage {
required int64 checksum = 2;
}
+message DeviceProfieData {
+ required float desktop_rows = 1;
+ required float desktop_cols = 2;
+ required float hotseat_count = 3;
+ required int32 allapps_rank = 4;
+}
+
message Journal {
required int32 app_version = 1;
+
+ // Time when the backup was created
required int64 t = 2;
+
+ // Total bytes written during the last backup
+ // OBSOLETE: A state may contain entries which are already present in the backup
+ // and were not written in the last backup
optional int64 bytes = 3;
+
+ // Total entries written during the last backup
+ // OBSOLETE: A state may contain entries which are already present in the backup
+ // and were not written in the last backup
optional int32 rows = 4;
+
+ // Valid keys for this state
repeated Key key = 5;
+
+ // Backup format version.
+ optional int32 backup_version = 6 [default = 1];
+
+ optional DeviceProfieData profile = 7;
}
message Favorite {
diff --git a/res/drawable-hdpi/hand.png b/res/drawable-hdpi/hand.png
deleted file mode 100644
index bd4f6dfbc..000000000
--- a/res/drawable-hdpi/hand.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_home_search_normal_holo.png b/res/drawable-hdpi/ic_home_search_normal_holo.png
deleted file mode 100644
index 3f64d6823..000000000
--- a/res/drawable-hdpi/ic_home_search_normal_holo.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_home_voice_search_holo.png b/res/drawable-hdpi/ic_home_voice_search_holo.png
deleted file mode 100644
index dae54464a..000000000
--- a/res/drawable-hdpi/ic_home_voice_search_holo.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_pageindicator_current.png b/res/drawable-hdpi/ic_pageindicator_current.png
index 2e841f5f5..283f44d37 100644
--- a/res/drawable-hdpi/ic_pageindicator_current.png
+++ b/res/drawable-hdpi/ic_pageindicator_current.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_pageindicator_default.png b/res/drawable-hdpi/ic_pageindicator_default.png
index 07ab94865..47b998967 100644
--- a/res/drawable-hdpi/ic_pageindicator_default.png
+++ b/res/drawable-hdpi/ic_pageindicator_default.png
Binary files differ
diff --git a/res/drawable-hdpi/search_frame.9.png b/res/drawable-hdpi/search_frame.9.png
deleted file mode 100644
index 15ca1f4e6..000000000
--- a/res/drawable-hdpi/search_frame.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/tab_selected_focused_holo.9.png b/res/drawable-hdpi/tab_selected_focused_holo.9.png
deleted file mode 100644
index 673e3bf10..000000000
--- a/res/drawable-hdpi/tab_selected_focused_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/tab_selected_holo.9.png b/res/drawable-hdpi/tab_selected_holo.9.png
deleted file mode 100644
index d57df98b5..000000000
--- a/res/drawable-hdpi/tab_selected_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/tab_selected_pressed_focused_holo.9.png b/res/drawable-hdpi/tab_selected_pressed_focused_holo.9.png
deleted file mode 100644
index 4b312d9e3..000000000
--- a/res/drawable-hdpi/tab_selected_pressed_focused_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/tab_selected_pressed_holo.9.png b/res/drawable-hdpi/tab_selected_pressed_holo.9.png
deleted file mode 100644
index 6278eef47..000000000
--- a/res/drawable-hdpi/tab_selected_pressed_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/tab_unselected_focused_holo.9.png b/res/drawable-hdpi/tab_unselected_focused_holo.9.png
deleted file mode 100644
index 294991d79..000000000
--- a/res/drawable-hdpi/tab_unselected_focused_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/tab_unselected_holo.9.png b/res/drawable-hdpi/tab_unselected_holo.9.png
deleted file mode 100644
index 19532ab10..000000000
--- a/res/drawable-hdpi/tab_unselected_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/tab_unselected_pressed_focused_holo.9.png b/res/drawable-hdpi/tab_unselected_pressed_focused_holo.9.png
deleted file mode 100644
index 5140b3523..000000000
--- a/res/drawable-hdpi/tab_unselected_pressed_focused_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/tab_unselected_pressed_holo.9.png b/res/drawable-hdpi/tab_unselected_pressed_holo.9.png
deleted file mode 100644
index aadc6f87b..000000000
--- a/res/drawable-hdpi/tab_unselected_pressed_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-land-hdpi/ic_home_voice_search_holo.png b/res/drawable-land-hdpi/ic_home_voice_search_holo.png
deleted file mode 100644
index 5a7fc99e4..000000000
--- a/res/drawable-land-hdpi/ic_home_voice_search_holo.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-land-mdpi/ic_home_voice_search_holo.png b/res/drawable-land-mdpi/ic_home_voice_search_holo.png
deleted file mode 100644
index ee7dde52c..000000000
--- a/res/drawable-land-mdpi/ic_home_voice_search_holo.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-land-xhdpi/ic_home_voice_search_holo.png b/res/drawable-land-xhdpi/ic_home_voice_search_holo.png
deleted file mode 100644
index 56bbbbb06..000000000
--- a/res/drawable-land-xhdpi/ic_home_voice_search_holo.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-land-xxhdpi/ic_home_voice_search_holo.png b/res/drawable-land-xxhdpi/ic_home_voice_search_holo.png
deleted file mode 100644
index 6ea7368be..000000000
--- a/res/drawable-land-xxhdpi/ic_home_voice_search_holo.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/hand.png b/res/drawable-mdpi/hand.png
deleted file mode 100644
index fe5a035de..000000000
--- a/res/drawable-mdpi/hand.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_home_search_normal_holo.png b/res/drawable-mdpi/ic_home_search_normal_holo.png
deleted file mode 100644
index 7367c380c..000000000
--- a/res/drawable-mdpi/ic_home_search_normal_holo.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_home_voice_search_holo.png b/res/drawable-mdpi/ic_home_voice_search_holo.png
deleted file mode 100644
index f211a7b9c..000000000
--- a/res/drawable-mdpi/ic_home_voice_search_holo.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_pageindicator_current.png b/res/drawable-mdpi/ic_pageindicator_current.png
index 08f43b4c1..b41e1bb67 100644
--- a/res/drawable-mdpi/ic_pageindicator_current.png
+++ b/res/drawable-mdpi/ic_pageindicator_current.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_pageindicator_default.png b/res/drawable-mdpi/ic_pageindicator_default.png
index 635be4a37..e36c25cf1 100644
--- a/res/drawable-mdpi/ic_pageindicator_default.png
+++ b/res/drawable-mdpi/ic_pageindicator_default.png
Binary files differ
diff --git a/res/drawable-mdpi/search_frame.9.png b/res/drawable-mdpi/search_frame.9.png
deleted file mode 100644
index 058905bdb..000000000
--- a/res/drawable-mdpi/search_frame.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/tab_selected_focused_holo.9.png b/res/drawable-mdpi/tab_selected_focused_holo.9.png
deleted file mode 100644
index c9972e74b..000000000
--- a/res/drawable-mdpi/tab_selected_focused_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/tab_selected_holo.9.png b/res/drawable-mdpi/tab_selected_holo.9.png
deleted file mode 100644
index 587337caf..000000000
--- a/res/drawable-mdpi/tab_selected_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/tab_selected_pressed_focused_holo.9.png b/res/drawable-mdpi/tab_selected_pressed_focused_holo.9.png
deleted file mode 100644
index 284f5344a..000000000
--- a/res/drawable-mdpi/tab_selected_pressed_focused_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/tab_selected_pressed_holo.9.png b/res/drawable-mdpi/tab_selected_pressed_holo.9.png
deleted file mode 100644
index 155c4fc75..000000000
--- a/res/drawable-mdpi/tab_selected_pressed_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/tab_unselected_focused_holo.9.png b/res/drawable-mdpi/tab_unselected_focused_holo.9.png
deleted file mode 100644
index f0cecd183..000000000
--- a/res/drawable-mdpi/tab_unselected_focused_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/tab_unselected_holo.9.png b/res/drawable-mdpi/tab_unselected_holo.9.png
deleted file mode 100644
index a2dbf42b7..000000000
--- a/res/drawable-mdpi/tab_unselected_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/tab_unselected_pressed_focused_holo.9.png b/res/drawable-mdpi/tab_unselected_pressed_focused_holo.9.png
deleted file mode 100644
index f1a2819c5..000000000
--- a/res/drawable-mdpi/tab_unselected_pressed_focused_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/tab_unselected_pressed_holo.9.png b/res/drawable-mdpi/tab_unselected_pressed_holo.9.png
deleted file mode 100644
index b1223fe3c..000000000
--- a/res/drawable-mdpi/tab_unselected_pressed_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/hand.png b/res/drawable-xhdpi/hand.png
deleted file mode 100644
index 35b678c89..000000000
--- a/res/drawable-xhdpi/hand.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_home_search_normal_holo.png b/res/drawable-xhdpi/ic_home_search_normal_holo.png
deleted file mode 100644
index 0fe1cd133..000000000
--- a/res/drawable-xhdpi/ic_home_search_normal_holo.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_home_voice_search_holo.png b/res/drawable-xhdpi/ic_home_voice_search_holo.png
deleted file mode 100644
index 1fc5cc8bb..000000000
--- a/res/drawable-xhdpi/ic_home_voice_search_holo.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_pageindicator_current.png b/res/drawable-xhdpi/ic_pageindicator_current.png
index 0e9a52f6d..8fa774dee 100644
--- a/res/drawable-xhdpi/ic_pageindicator_current.png
+++ b/res/drawable-xhdpi/ic_pageindicator_current.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_pageindicator_default.png b/res/drawable-xhdpi/ic_pageindicator_default.png
index d0f14cdfb..8eb5eb08d 100644
--- a/res/drawable-xhdpi/ic_pageindicator_default.png
+++ b/res/drawable-xhdpi/ic_pageindicator_default.png
Binary files differ
diff --git a/res/drawable-xhdpi/search_frame.9.png b/res/drawable-xhdpi/search_frame.9.png
deleted file mode 100644
index 32a07143e..000000000
--- a/res/drawable-xhdpi/search_frame.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tab_selected_focused_holo.9.png b/res/drawable-xhdpi/tab_selected_focused_holo.9.png
deleted file mode 100644
index 03cfb0945..000000000
--- a/res/drawable-xhdpi/tab_selected_focused_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tab_selected_holo.9.png b/res/drawable-xhdpi/tab_selected_holo.9.png
deleted file mode 100644
index e4229f26b..000000000
--- a/res/drawable-xhdpi/tab_selected_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tab_selected_pressed_focused_holo.9.png b/res/drawable-xhdpi/tab_selected_pressed_focused_holo.9.png
deleted file mode 100644
index 24127117f..000000000
--- a/res/drawable-xhdpi/tab_selected_pressed_focused_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tab_selected_pressed_holo.9.png b/res/drawable-xhdpi/tab_selected_pressed_holo.9.png
deleted file mode 100644
index e862cb121..000000000
--- a/res/drawable-xhdpi/tab_selected_pressed_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tab_unselected_focused_holo.9.png b/res/drawable-xhdpi/tab_unselected_focused_holo.9.png
deleted file mode 100644
index f3a5cbde8..000000000
--- a/res/drawable-xhdpi/tab_unselected_focused_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tab_unselected_holo.9.png b/res/drawable-xhdpi/tab_unselected_holo.9.png
deleted file mode 100644
index 946517378..000000000
--- a/res/drawable-xhdpi/tab_unselected_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tab_unselected_pressed_focused_holo.9.png b/res/drawable-xhdpi/tab_unselected_pressed_focused_holo.9.png
deleted file mode 100644
index 16536003f..000000000
--- a/res/drawable-xhdpi/tab_unselected_pressed_focused_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tab_unselected_pressed_holo.9.png b/res/drawable-xhdpi/tab_unselected_pressed_holo.9.png
deleted file mode 100644
index f1eb67323..000000000
--- a/res/drawable-xhdpi/tab_unselected_pressed_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/hand.png b/res/drawable-xxhdpi/hand.png
deleted file mode 100644
index 88c2a882c..000000000
--- a/res/drawable-xxhdpi/hand.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_home_search_normal_holo.png b/res/drawable-xxhdpi/ic_home_search_normal_holo.png
deleted file mode 100644
index a9523d3cc..000000000
--- a/res/drawable-xxhdpi/ic_home_search_normal_holo.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_home_voice_search_holo.png b/res/drawable-xxhdpi/ic_home_voice_search_holo.png
deleted file mode 100644
index c9c0b50bd..000000000
--- a/res/drawable-xxhdpi/ic_home_voice_search_holo.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_pageindicator_current.png b/res/drawable-xxhdpi/ic_pageindicator_current.png
index b74e92ea7..22b290e69 100644
--- a/res/drawable-xxhdpi/ic_pageindicator_current.png
+++ b/res/drawable-xxhdpi/ic_pageindicator_current.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_pageindicator_default.png b/res/drawable-xxhdpi/ic_pageindicator_default.png
index e362ece71..e608cae30 100644
--- a/res/drawable-xxhdpi/ic_pageindicator_default.png
+++ b/res/drawable-xxhdpi/ic_pageindicator_default.png
Binary files differ
diff --git a/res/drawable-xxhdpi/search_bg_panel.9.png b/res/drawable-xxhdpi/search_bg_panel.9.png
deleted file mode 100644
index 85cae17bc..000000000
--- a/res/drawable-xxhdpi/search_bg_panel.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/search_frame.9.png b/res/drawable-xxhdpi/search_frame.9.png
deleted file mode 100644
index f297bf19c..000000000
--- a/res/drawable-xxhdpi/search_frame.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/tab_selected_focused_holo.9.png b/res/drawable-xxhdpi/tab_selected_focused_holo.9.png
deleted file mode 100644
index 2400c65d5..000000000
--- a/res/drawable-xxhdpi/tab_selected_focused_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/tab_selected_holo.9.png b/res/drawable-xxhdpi/tab_selected_holo.9.png
deleted file mode 100644
index 5067cbbfe..000000000
--- a/res/drawable-xxhdpi/tab_selected_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/tab_selected_pressed_holo.9.png b/res/drawable-xxhdpi/tab_selected_pressed_holo.9.png
deleted file mode 100644
index 84c246da4..000000000
--- a/res/drawable-xxhdpi/tab_selected_pressed_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/tab_unselected_focused_holo.9.png b/res/drawable-xxhdpi/tab_unselected_focused_holo.9.png
deleted file mode 100644
index 939e0c3e0..000000000
--- a/res/drawable-xxhdpi/tab_unselected_focused_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/tab_unselected_holo.9.png b/res/drawable-xxhdpi/tab_unselected_holo.9.png
deleted file mode 100644
index 62ca6cf84..000000000
--- a/res/drawable-xxhdpi/tab_unselected_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/tab_unselected_pressed_holo.9.png b/res/drawable-xxhdpi/tab_unselected_pressed_holo.9.png
deleted file mode 100644
index 58ac0d649..000000000
--- a/res/drawable-xxhdpi/tab_unselected_pressed_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable/tab_widget_indicator_selector.xml b/res/drawable/tab_widget_indicator_selector.xml
deleted file mode 100644
index d06f757ce..000000000
--- a/res/drawable/tab_widget_indicator_selector.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <!-- Non focused states -->
- <item android:state_focused="false" android:state_selected="true" android:state_pressed="false" android:drawable="@drawable/tab_selected_holo" />
-
- <!-- Focused states -->
- <item android:state_focused="true" android:state_selected="false" android:state_pressed="false" android:drawable="@drawable/tab_unselected_focused_holo" />
- <item android:state_focused="true" android:state_selected="true" android:state_pressed="false" android:drawable="@drawable/tab_selected_focused_holo" />
-
- <!-- Pressed -->
- <!-- Non focused states -->
- <item android:state_focused="false" android:state_selected="false" android:state_pressed="true" android:drawable="@drawable/tab_unselected_pressed_holo" />
- <item android:state_focused="false" android:state_selected="true" android:state_pressed="true" android:drawable="@drawable/tab_selected_pressed_holo" />
-
- <!-- Focused states -->
- <item android:state_focused="true" android:state_selected="false" android:state_pressed="true" android:drawable="@drawable/tab_unselected_pressed_focused_holo" />
- <item android:state_focused="true" android:state_selected="true" android:state_pressed="true" android:drawable="@drawable/tab_selected_pressed_focused_holo" />
-</selector>
diff --git a/res/layout-land/launcher.xml b/res/layout-land/launcher.xml
index 8cd867366..6f95bd506 100644
--- a/res/layout-land/launcher.xml
+++ b/res/layout-land/launcher.xml
@@ -15,20 +15,20 @@
-->
<!-- Full screen view projects under the status bar and contains the background -->
-<FrameLayout
+<com.android.launcher3.LauncherRootView
xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3"
+ xmlns:launcher="http://schemas.android.com/apk/res-auto"
android:id="@+id/launcher"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:background="@drawable/workspace_bg">
+ android:background="@drawable/workspace_bg"
+ android:fitsSystemWindows="true">
<com.android.launcher3.DragLayer
android:id="@+id/drag_layer"
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:fitsSystemWindows="true">
+ android:layout_height="match_parent">
<com.android.launcher3.FocusIndicatorView
android:id="@+id/focus_indicator"
@@ -63,4 +63,11 @@
android:layout_height="match_parent"
android:visibility="invisible" />
</com.android.launcher3.DragLayer>
-</FrameLayout>
+
+ <ViewStub
+ android:id="@+id/launcher_overlay_stub"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:inflatedId="@+id/launcher_overlay"
+ android:layout="@layout/launcher_overlay" />
+</com.android.launcher3.LauncherRootView>
diff --git a/res/layout-land/longpress_cling.xml b/res/layout-land/longpress_cling.xml
index 93bbc077a..9672dd8a0 100644
--- a/res/layout-land/longpress_cling.xml
+++ b/res/layout-land/longpress_cling.xml
@@ -1,9 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3"
+ xmlns:launcher="http://schemas.android.com/apk/res-auto"
android:id="@+id/longpress_cling"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ launcher:layout_ignoreInsets="true"
android:background="@color/cling_scrim_background"
android:orientation="vertical" >
diff --git a/res/layout-land/migration_cling.xml b/res/layout-land/migration_cling.xml
index 307cba8a8..db93da87a 100644
--- a/res/layout-land/migration_cling.xml
+++ b/res/layout-land/migration_cling.xml
@@ -15,9 +15,11 @@
limitations under the License.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:launcher="http://schemas.android.com/apk/res-auto"
android:id="@+id/migration_cling"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ launcher:layout_ignoreInsets="true"
android:background="#FF009688"
android:baselineAligned="false"
android:gravity="center_vertical" >
diff --git a/res/layout-land/qsb.xml b/res/layout-land/qsb.xml
deleted file mode 100644
index d56e380d0..000000000
--- a/res/layout-land/qsb.xml
+++ /dev/null
@@ -1,50 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical">
- <!-- Global search icon -->
- <com.android.launcher3.HolographicImageView
- style="@style/SearchButton"
- android:id="@+id/search_button"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_alignParentTop="true"
- android:scaleType="center"
- android:src="@drawable/ic_home_search_normal_holo"
- android:adjustViewBounds="true"
- android:onClick="onClickSearchButton"
- android:focusable="true"
- android:clickable="true"
- android:contentDescription="@string/accessibility_search_button" />
-
- <!-- Voice search icon -->
- <com.android.launcher3.HolographicImageView
- style="@style/SearchButton"
- android:id="@+id/voice_button"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_alignParentBottom="true"
- android:scaleType="center"
- android:src="@drawable/ic_home_voice_search_holo"
- android:adjustViewBounds="true"
- android:onClick="onClickVoiceButton"
- android:focusable="true"
- android:clickable="true"
- android:contentDescription="@string/accessibility_voice_search_button" />
-</LinearLayout>
diff --git a/res/layout-port/launcher.xml b/res/layout-port/launcher.xml
index 9e98d4257..af30a32e5 100644
--- a/res/layout-port/launcher.xml
+++ b/res/layout-port/launcher.xml
@@ -15,14 +15,15 @@
-->
<!-- Full screen view projects under the status bar and contains the background -->
-<FrameLayout
+<com.android.launcher3.LauncherRootView
xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3"
+ xmlns:launcher="http://schemas.android.com/apk/res-auto"
android:id="@+id/launcher"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:background="@drawable/workspace_bg">
+ android:background="@drawable/workspace_bg"
+ android:fitsSystemWindows="true">
<com.android.launcher3.DragLayer
android:id="@+id/drag_layer"
@@ -65,22 +66,17 @@
android:id="@+id/search_drop_target_bar"
layout="@layout/search_drop_target_bar" />
- <!-- This is the search bar voice button proxy view. It allows us to have a larger
- touch target than the microphone constrained by the search bar bounds. -->
- <com.android.launcher3.DrawableStateProxyView
- android:id="@+id/voice_button_proxy"
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:layout_gravity="top|end"
- android:clickable="true"
- android:onClick="onClickVoiceButton"
- android:importantForAccessibility="no"
- launcher:sourceViewId="@+id/voice_button" />
-
<include layout="@layout/apps_customize_pane"
android:id="@+id/apps_customize_pane"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="invisible" />
</com.android.launcher3.DragLayer>
-</FrameLayout>
+
+ <ViewStub
+ android:id="@+id/launcher_overlay_stub"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:inflatedId="@+id/launcher_overlay"
+ android:layout="@layout/launcher_overlay" />
+</com.android.launcher3.LauncherRootView>
diff --git a/res/layout-port/longpress_cling.xml b/res/layout-port/longpress_cling.xml
index 8e35f5c1a..c0b526713 100644
--- a/res/layout-port/longpress_cling.xml
+++ b/res/layout-port/longpress_cling.xml
@@ -1,9 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3"
+ xmlns:launcher="http://schemas.android.com/apk/res-auto"
android:id="@+id/longpress_cling"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ launcher:layout_ignoreInsets="true"
android:background="@color/cling_scrim_background" >
<FrameLayout
diff --git a/res/layout-port/migration_cling.xml b/res/layout-port/migration_cling.xml
index dde8dbcdb..81689d38b 100644
--- a/res/layout-port/migration_cling.xml
+++ b/res/layout-port/migration_cling.xml
@@ -15,9 +15,11 @@
limitations under the License.
-->
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:launcher="http://schemas.android.com/apk/res-auto"
android:id="@+id/migration_cling"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ launcher:layout_ignoreInsets="true"
android:background="#FF009688" >
<RelativeLayout
diff --git a/res/layout-port/qsb.xml b/res/layout-port/qsb.xml
deleted file mode 100644
index 4c9963dfb..000000000
--- a/res/layout-port/qsb.xml
+++ /dev/null
@@ -1,72 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<RelativeLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="@drawable/search_frame">
- <!-- Global search icon -->
- <com.android.launcher3.HolographicLinearLayout
- style="@style/SearchButton.WithPaddingStart"
- launcher:sourceImageViewId="@+id/search_button"
- android:id="@+id/search_button_container"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_gravity="center_vertical"
- android:layout_centerVertical="true"
- android:layout_alignParentStart="true"
- android:layout_toStartOf="@+id/voice_button_container"
- android:onClick="onClickSearchButton"
- android:focusable="true"
- android:clickable="true"
- android:contentDescription="@string/accessibility_search_button">
- <ImageView
- android:id="@+id/search_button"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_gravity="start"
- android:scaleType="fitCenter"
- android:src="@drawable/ic_home_search_normal_holo"
- android:adjustViewBounds="true" />
- </com.android.launcher3.HolographicLinearLayout>
-
- <!-- Voice search icon -->
- <com.android.launcher3.HolographicLinearLayout
- style="@style/SearchButton"
- launcher:sourceImageViewId="@+id/voice_button"
- android:id="@+id/voice_button_container"
- android:layout_width="@dimen/app_icon_size"
- android:layout_height="match_parent"
- android:layout_gravity="center_vertical"
- android:layout_centerVertical="true"
- android:layout_alignParentEnd="true"
- android:paddingEnd="8dp"
- android:paddingRight="8dp"
- android:onClick="onClickVoiceButton"
- android:focusable="true"
- android:clickable="true"
- android:contentDescription="@string/accessibility_voice_search_button">
- <ImageView
- android:id="@+id/voice_button"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_gravity="end"
- android:scaleType="fitCenter"
- android:src="@drawable/ic_home_voice_search_holo"
- android:adjustViewBounds="true" />
- </com.android.launcher3.HolographicLinearLayout>
-</RelativeLayout>
diff --git a/res/layout-sw600dp-port/longpress_cling.xml b/res/layout-sw600dp-port/longpress_cling.xml
index b42d697a5..c4573d535 100644
--- a/res/layout-sw600dp-port/longpress_cling.xml
+++ b/res/layout-sw600dp-port/longpress_cling.xml
@@ -1,9 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3"
+ xmlns:launcher="http://schemas.android.com/apk/res-auto"
android:id="@+id/longpress_cling"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ launcher:layout_ignoreInsets="true"
android:background="@color/cling_scrim_background"
android:orientation="vertical" >
diff --git a/res/layout-sw720dp/launcher.xml b/res/layout-sw720dp/launcher.xml
index 62615411f..960ccf330 100644
--- a/res/layout-sw720dp/launcher.xml
+++ b/res/layout-sw720dp/launcher.xml
@@ -15,20 +15,20 @@
-->
<!-- Full screen view projects under the status bar and contains the background -->
-<FrameLayout
+<com.android.launcher3.LauncherRootView
xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3"
+ xmlns:launcher="http://schemas.android.com/apk/res-auto"
android:id="@+id/launcher"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:background="@drawable/workspace_bg">
+ android:background="@drawable/workspace_bg"
+ android:fitsSystemWindows="true">
<com.android.launcher3.DragLayer
android:id="@+id/drag_layer"
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:fitsSystemWindows="true">
+ android:layout_height="match_parent">
<com.android.launcher3.FocusIndicatorView
android:id="@+id/focus_indicator"
@@ -66,20 +66,18 @@
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" />
- <com.android.launcher3.DrawableStateProxyView
- android:id="@+id/voice_button_proxy"
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:layout_gravity="top|end"
- android:clickable="true"
- android:onClick="onClickVoiceButton"
- android:importantForAccessibility="no"
- launcher:sourceViewId="@+id/voice_button" />
-
<include layout="@layout/apps_customize_pane"
android:id="@+id/apps_customize_pane"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="invisible" />
</com.android.launcher3.DragLayer>
-</FrameLayout>
+
+ <ViewStub
+ android:id="@+id/launcher_overlay_stub"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:inflatedId="@+id/launcher_overlay"
+ android:layout="@layout/launcher_overlay" />
+
+</com.android.launcher3.LauncherRootView>
diff --git a/res/layout-sw720dp/market_button.xml b/res/layout-sw720dp/market_button.xml
deleted file mode 100644
index 7eaeafac3..000000000
--- a/res/layout-sw720dp/market_button.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<TextView
- xmlns:android="http://schemas.android.com/apk/res/android"
- style="@style/MarketButton"
- android:onClick="onClickAppMarketButton"
- android:gravity="center"
- android:paddingLeft="32dp"
- android:paddingRight="32dp"
- android:drawablePadding="10dp"
- android:background="@drawable/tab_widget_indicator_selector"
- android:text="@string/market"
- android:contentDescription="@string/market"
- android:textColor="@color/workspace_all_apps_and_delete_zone_text_color"
- android:textStyle="bold"
- android:textSize="14sp"
- android:textAllCaps="true"
- android:shadowColor="@color/workspace_all_apps_and_delete_zone_text_shadow_color"
- android:shadowDx="0.0"
- android:shadowDy="0.0"
- android:shadowRadius="2.0"
- android:focusable="true"
- android:clickable="true" />
diff --git a/res/layout-sw720dp/qsb.xml b/res/layout-sw720dp/qsb.xml
deleted file mode 100644
index 4c9963dfb..000000000
--- a/res/layout-sw720dp/qsb.xml
+++ /dev/null
@@ -1,72 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<RelativeLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="@drawable/search_frame">
- <!-- Global search icon -->
- <com.android.launcher3.HolographicLinearLayout
- style="@style/SearchButton.WithPaddingStart"
- launcher:sourceImageViewId="@+id/search_button"
- android:id="@+id/search_button_container"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_gravity="center_vertical"
- android:layout_centerVertical="true"
- android:layout_alignParentStart="true"
- android:layout_toStartOf="@+id/voice_button_container"
- android:onClick="onClickSearchButton"
- android:focusable="true"
- android:clickable="true"
- android:contentDescription="@string/accessibility_search_button">
- <ImageView
- android:id="@+id/search_button"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_gravity="start"
- android:scaleType="fitCenter"
- android:src="@drawable/ic_home_search_normal_holo"
- android:adjustViewBounds="true" />
- </com.android.launcher3.HolographicLinearLayout>
-
- <!-- Voice search icon -->
- <com.android.launcher3.HolographicLinearLayout
- style="@style/SearchButton"
- launcher:sourceImageViewId="@+id/voice_button"
- android:id="@+id/voice_button_container"
- android:layout_width="@dimen/app_icon_size"
- android:layout_height="match_parent"
- android:layout_gravity="center_vertical"
- android:layout_centerVertical="true"
- android:layout_alignParentEnd="true"
- android:paddingEnd="8dp"
- android:paddingRight="8dp"
- android:onClick="onClickVoiceButton"
- android:focusable="true"
- android:clickable="true"
- android:contentDescription="@string/accessibility_voice_search_button">
- <ImageView
- android:id="@+id/voice_button"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_gravity="end"
- android:scaleType="fitCenter"
- android:src="@drawable/ic_home_voice_search_holo"
- android:adjustViewBounds="true" />
- </com.android.launcher3.HolographicLinearLayout>
-</RelativeLayout>
diff --git a/res/layout/apps_customize_pane.xml b/res/layout/apps_customize_pane.xml
index bf5f71b90..e42576ffe 100644
--- a/res/layout/apps_customize_pane.xml
+++ b/res/layout/apps_customize_pane.xml
@@ -15,7 +15,7 @@
-->
<com.android.launcher3.AppsCustomizeTabHost
xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3"
+ xmlns:launcher="http://schemas.android.com/apk/res-auto"
android:clipChildren="false">
<LinearLayout
diff --git a/res/layout/apps_customize_widget.xml b/res/layout/apps_customize_widget.xml
index e299b32b0..a8344e3ff 100644
--- a/res/layout/apps_customize_widget.xml
+++ b/res/layout/apps_customize_widget.xml
@@ -15,7 +15,7 @@
-->
<com.android.launcher3.PagedViewWidget
xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3"
+ xmlns:launcher="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
@@ -66,7 +66,7 @@
android:background="@color/widget_text_panel"
android:orientation="horizontal">
<!-- The name of the widget. -->
- <TextView xmlns:android="http://schemas.android.com/apk/res/android"
+ <TextView
android:id="@+id/widget_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -85,7 +85,7 @@
<!-- The original dimensions of the widget (can't be the same text as above due to different
style. -->
- <TextView xmlns:android="http://schemas.android.com/apk/res/android"
+ <TextView
android:id="@+id/widget_dims"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
diff --git a/res/layout/drop_target_bar.xml b/res/layout/drop_target_bar.xml
deleted file mode 100644
index f38a50014..000000000
--- a/res/layout/drop_target_bar.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<merge xmlns:android="http://schemas.android.com/apk/res/android">
- <FrameLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- style="@style/DropTargetButtonContainer"
- android:layout_weight="1">
- <!-- Delete target -->
- <com.android.launcher3.DeleteDropTarget
- style="@style/DropTargetButton"
- android:id="@+id/delete_target_text"
- android:text="@string/delete_zone_label_workspace"
- android:drawableStart="@drawable/remove_target_selector" />
- </FrameLayout>
- <FrameLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- style="@style/DropTargetButtonContainer"
- android:layout_weight="1">
- <!-- Info target -->
- <com.android.launcher3.InfoDropTarget
- style="@style/DropTargetButton"
- android:id="@+id/info_target_text"
- android:text="@string/info_target_label"
- android:drawableStart="@drawable/info_target_selector" />
- </FrameLayout>
-</merge>
diff --git a/res/layout/hotseat.xml b/res/layout/hotseat.xml
index dc9ed2a6f..7bef889a9 100644
--- a/res/layout/hotseat.xml
+++ b/res/layout/hotseat.xml
@@ -15,7 +15,7 @@
-->
<com.android.launcher3.Hotseat
xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3">
+ xmlns:launcher="http://schemas.android.com/apk/res-auto">
<com.android.launcher3.CellLayout
android:id="@+id/layout"
android:layout_width="wrap_content"
diff --git a/res/layout/tab_widget_indicator.xml b/res/layout/launcher_overlay.xml
index de7c50ec4..b35a2d8ae 100644
--- a/res/layout/tab_widget_indicator.xml
+++ b/res/layout/launcher_overlay.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
+<!-- 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.
@@ -14,6 +14,7 @@
limitations under the License.
-->
-<com.android.launcher3.AccessibleTabView
+<com.android.launcher3.InsettableFrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
- style="@style/TabIndicator.AppsCustomize" />
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
diff --git a/res/layout-sw720dp/external_widget_drop_list_item.xml b/res/layout/launcher_overlay_example.xml
index 48e333b3a..7d92d4f0d 100644
--- a/res/layout-sw720dp/external_widget_drop_list_item.xml
+++ b/res/layout/launcher_overlay_example.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
+<!-- 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.
@@ -14,26 +14,26 @@
limitations under the License.
-->
-<LinearLayout
+<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
-
+ xmlns:launcher="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
- android:layout_height="64dp">
- <ImageView
- android:id="@+id/provider_icon"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_vertical"
- android:layout_marginStart="20dp"
- android:maxWidth="32dp"
- android:maxHeight="32dp"
- android:scaleType="fitCenter"
- android:src="@mipmap/ic_launcher_application" />
- <TextView
- android:id="@+id/provider"
+ android:layout_height="match_parent"
+ launcher:layout_ignoreInsets="true">
+
+ <FrameLayout
+ android:id="@+id/search_overlay"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:layout_marginStart="5dp"
- android:gravity="center_vertical"
- android:textSize="18sp" />
-</LinearLayout>
+ android:background="#ff00ff00"
+ android:visibility="invisible" />
+
+ <FrameLayout
+ android:id="@+id/search_box"
+ android:layout_width="match_parent"
+ android:layout_height="48dp"
+ android:layout_marginLeft="8dp"
+ android:layout_marginRight="8dp"
+ android:layout_marginTop="36dp"
+ android:background="#ffff0000" />
+</FrameLayout>
diff --git a/res/layout/market_button.xml b/res/layout/market_button.xml
deleted file mode 100644
index 41e6ec7cc..000000000
--- a/res/layout/market_button.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<TextView
- xmlns:android="http://schemas.android.com/apk/res/android"
- style="@style/MarketButton"
- android:onClick="onClickAppMarketButton"
- android:gravity="center"
- android:paddingLeft="16dp"
- android:paddingRight="16dp"
- android:background="@drawable/tab_widget_indicator_selector"
- android:contentDescription="@string/market"
- android:shadowColor="@color/workspace_all_apps_and_delete_zone_text_shadow_color"
- android:shadowDx="0.0"
- android:shadowDy="0.0"
- android:shadowRadius="2.0"
- android:focusable="true"
- android:clickable="true" />
diff --git a/res/layout/overview_panel.xml b/res/layout/overview_panel.xml
index 558900c7d..4b7423eba 100644
--- a/res/layout/overview_panel.xml
+++ b/res/layout/overview_panel.xml
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<!--
+ Copyright (C) 2013 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.
@@ -13,47 +14,50 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<FrameLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="wrap_content"
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|bottom"
- android:orientation="horizontal">
+ android:gravity="top"
+ android:orientation="horizontal" >
<TextView
android:id="@+id/wallpaper_button"
- android:layout_width="wrap_content"
+ android:layout_width="0dp"
android:layout_height="wrap_content"
- android:layout_gravity="start|top"
- android:text="@string/wallpaper_button_text"
+ android:layout_weight="1"
android:drawablePadding="4dp"
android:drawableTop="@drawable/wallpaper_button"
- android:gravity="center_horizontal"
android:fontFamily="sans-serif-condensed"
+ android:gravity="center_horizontal"
+ android:text="@string/wallpaper_button_text"
android:textAllCaps="true"
android:textSize="12sp" />
+
<TextView
android:id="@+id/widget_button"
- android:layout_width="wrap_content"
+ android:layout_width="0dp"
android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal|top"
- android:text="@string/widget_button_text"
+ android:layout_weight="1"
android:drawablePadding="4dp"
- android:gravity="center_horizontal"
android:drawableTop="@drawable/widget_button"
android:fontFamily="sans-serif-condensed"
+ android:gravity="center_horizontal"
+ android:text="@string/widget_button_text"
android:textAllCaps="true"
- android:textSize="12sp"/>
+ android:textSize="12sp" />
+
<TextView
android:id="@+id/settings_button"
- android:layout_width="wrap_content"
+ android:layout_width="0dp"
android:layout_height="wrap_content"
- android:layout_gravity="end|top"
- android:text="@string/settings_button_text"
+ android:layout_weight="1"
android:drawablePadding="4dp"
- android:gravity="center_horizontal"
android:drawableTop="@drawable/setting_button"
android:fontFamily="sans-serif-condensed"
+ android:gravity="center_horizontal"
+ android:text="@string/settings_button_text"
android:textAllCaps="true"
android:textSize="12sp" />
-</FrameLayout>
+
+</LinearLayout> \ No newline at end of file
diff --git a/res/layout/page_indicator.xml b/res/layout/page_indicator.xml
index 14eff75d0..68fe3dd60 100644
--- a/res/layout/page_indicator.xml
+++ b/res/layout/page_indicator.xml
@@ -15,7 +15,7 @@
-->
<com.android.launcher3.PageIndicator
xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3"
+ xmlns:launcher="http://schemas.android.com/apk/res-auto"
android:animateLayoutChanges="true"
launcher:windowSize="@integer/config_maxNumberOfPageIndicatorsToShow">
</com.android.launcher3.PageIndicator>
diff --git a/res/layout/page_indicator_marker.xml b/res/layout/page_indicator_marker.xml
index 7c0c38920..686d27569 100644
--- a/res/layout/page_indicator_marker.xml
+++ b/res/layout/page_indicator_marker.xml
@@ -15,7 +15,7 @@
-->
<com.android.launcher3.PageIndicatorMarker
xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3"
+ xmlns:launcher="http://schemas.android.com/apk/res-auto"
android:layout_width="16dp"
android:layout_height="16dp"
android:layout_gravity="center_vertical">
diff --git a/res/layout/search_drop_target_bar.xml b/res/layout/search_drop_target_bar.xml
index 2d51b93ab..af2d01634 100644
--- a/res/layout/search_drop_target_bar.xml
+++ b/res/layout/search_drop_target_bar.xml
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
+<!--
+ 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.
@@ -13,21 +14,45 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<com.android.launcher3.SearchDropTargetBar
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="horizontal"
- android:focusable="false"
+<com.android.launcher3.SearchDropTargetBar xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
- android:layout_height="match_parent">
+ android:layout_height="match_parent"
+ android:focusable="false"
+ android:orientation="horizontal" >
<!-- Drag specific targets container -->
+
<LinearLayout
android:id="@+id/drag_target_bar"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:layout_gravity="center">
+ android:layout_gravity="center" >
+
+ <FrameLayout
+ style="@style/DropTargetButtonContainer"
+ android:layout_weight="1" >
+
+ <!-- Delete target -->
- <include
- layout="@layout/drop_target_bar" />
+ <com.android.launcher3.DeleteDropTarget
+ android:id="@+id/delete_target_text"
+ style="@style/DropTargetButton"
+ android:drawableStart="@drawable/remove_target_selector"
+ android:text="@string/delete_zone_label_workspace" />
+ </FrameLayout>
+
+ <FrameLayout
+ style="@style/DropTargetButtonContainer"
+ android:layout_weight="1" >
+
+ <!-- Info target -->
+
+ <com.android.launcher3.InfoDropTarget
+ android:id="@+id/info_target_text"
+ style="@style/DropTargetButton"
+ android:drawableStart="@drawable/info_target_selector"
+ android:text="@string/info_target_label" />
+ </FrameLayout>
</LinearLayout>
-</com.android.launcher3.SearchDropTargetBar>
+
+</com.android.launcher3.SearchDropTargetBar> \ No newline at end of file
diff --git a/res/layout/user_folder.xml b/res/layout/user_folder.xml
index 4e5303ac0..ed8d43e46 100644
--- a/res/layout/user_folder.xml
+++ b/res/layout/user_folder.xml
@@ -16,7 +16,7 @@
<com.android.launcher3.Folder
xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3"
+ xmlns:launcher="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
@@ -45,6 +45,7 @@
android:hint="@string/folder_hint_text"
android:textSize="14sp"
android:textColor="#ff777777"
+ android:textColorHint="#ff808080"
android:textColorHighlight="#ffCCCCCC"
android:textCursorDrawable="@null"
android:gravity="center_horizontal"
diff --git a/res/layout/workspace_screen.xml b/res/layout/workspace_screen.xml
index 855cf39f5..83b319b72 100644
--- a/res/layout/workspace_screen.xml
+++ b/res/layout/workspace_screen.xml
@@ -16,7 +16,7 @@
<com.android.launcher3.CellLayout
xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3"
+ xmlns:launcher="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
diff --git a/res/mipmap-hdpi/ic_launcher_application.png b/res/mipmap-hdpi/ic_launcher_application.png
deleted file mode 100644
index b9aa101ad..000000000
--- a/res/mipmap-hdpi/ic_launcher_application.png
+++ /dev/null
Binary files differ
diff --git a/res/mipmap-mdpi/ic_launcher_application.png b/res/mipmap-mdpi/ic_launcher_application.png
deleted file mode 100644
index 4771b855f..000000000
--- a/res/mipmap-mdpi/ic_launcher_application.png
+++ /dev/null
Binary files differ
diff --git a/res/mipmap-xhdpi/ic_launcher_application.png b/res/mipmap-xhdpi/ic_launcher_application.png
deleted file mode 100644
index 932f0f791..000000000
--- a/res/mipmap-xhdpi/ic_launcher_application.png
+++ /dev/null
Binary files differ
diff --git a/res/mipmap-xxhdpi/ic_launcher_application.png b/res/mipmap-xxhdpi/ic_launcher_application.png
deleted file mode 100644
index 7fc739aaf..000000000
--- a/res/mipmap-xxhdpi/ic_launcher_application.png
+++ /dev/null
Binary files differ
diff --git a/res/values-af-land/strings.xml b/res/values-af-land/strings.xml
deleted file mode 100644
index b976926f0..000000000
--- a/res/values-af-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="delete_target_label" msgid="4155210680095864979"></string>
- <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
- <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml
index 4a4bb78a2..f37f08f3b 100644
--- a/res/values-af/strings.xml
+++ b/res/values-af/strings.xml
@@ -24,12 +24,13 @@
<string name="uid_name" msgid="7820867637514617527">"Android-kernprogramme"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
<string name="activity_not_found" msgid="8071924732094499514">"Program is nie geïnstalleer nie."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"Program is nie beskikbaar nie"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Afgelaaide program in veiligmodus gedeaktiveer"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"Legstukke gedeaktiveer in Veiligmodus"</string>
<string name="widgets_tab_label" msgid="2921133187116603919">"Legstukke"</string>
<string name="widget_adder" msgid="3201040140710381657">"Legstukke"</string>
<string name="toggle_weight_watcher" msgid="5645299835184636119">"Wys Mem"</string>
<string name="long_press_widget_to_add" msgid="7699152356777458215">"Raak en hou om \'n legstuk op te tel."</string>
- <string name="market" msgid="2619650989819296998">"Winkel"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="external_drop_widget_error" msgid="3165821058322217155">"Kan nie item op hierdie Tuisskerm laat los nie."</string>
<string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Kies legstuk om te skep"</string>
@@ -57,8 +58,6 @@
<string name="delete_target_label" msgid="1822697352535677073">"Verwyder"</string>
<string name="delete_target_uninstall_label" msgid="5100785476250872595">"Deïnstalleer"</string>
<string name="info_target_label" msgid="8053346143994679532">"Programinligting"</string>
- <string name="accessibility_search_button" msgid="1628520399424565142">"Soek"</string>
- <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Stemsoektog"</string>
<string name="accessibility_all_apps_button" msgid="2603132375383800483">"Programme"</string>
<string name="accessibility_delete_button" msgid="6466114477993744621">"Verwyder"</string>
<string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Deïnstalleer opdatering"</string>
diff --git a/res/values-am-land/strings.xml b/res/values-am-land/strings.xml
deleted file mode 100644
index b976926f0..000000000
--- a/res/values-am-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="delete_target_label" msgid="4155210680095864979"></string>
- <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
- <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml
index d77744c94..1a25f66cd 100644
--- a/res/values-am/strings.xml
+++ b/res/values-am/strings.xml
@@ -24,12 +24,13 @@
<string name="uid_name" msgid="7820867637514617527">"Android ዋና መተግበሪያዎች"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
<string name="activity_not_found" msgid="8071924732094499514">"መተግበሪያ አልተጫነም።"</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"መተግበሪያ አይገኝም"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"የወረደው መተግበሪያ ደህንነቱ በተጠበቀ ሁኔታ ውስጥ ተሰናክሏል"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"ምግብሮች በደህንነቱ የተጠበቀ ሁኔታ ተሰናክለዋል"</string>
<string name="widgets_tab_label" msgid="2921133187116603919">"ፍርግሞች"</string>
<string name="widget_adder" msgid="3201040140710381657">"ፍርግሞች"</string>
<string name="toggle_weight_watcher" msgid="5645299835184636119">"ማህደረ ማስታወሻ አሳይ"</string>
<string name="long_press_widget_to_add" msgid="7699152356777458215">"ፍርግም ለማንሳት ይንኩ እና ይያዙት"</string>
- <string name="market" msgid="2619650989819296998">"ግዛ"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="external_drop_widget_error" msgid="3165821058322217155">"ንጥሉን እዚህ የመነሻ ማያ ገጽ ላይ ማኖር አልተቻለም።"</string>
<string name="external_drop_widget_pick_title" msgid="3486317258037690630">"ለመፍጠር መግብር ይምረጡ"</string>
@@ -57,8 +58,6 @@
<string name="delete_target_label" msgid="1822697352535677073">"አስወግድ"</string>
<string name="delete_target_uninstall_label" msgid="5100785476250872595">"አራግፍ"</string>
<string name="info_target_label" msgid="8053346143994679532">"የመተግበሪያ መረጃ"</string>
- <string name="accessibility_search_button" msgid="1628520399424565142">"ፍለጋ"</string>
- <string name="accessibility_voice_search_button" msgid="4637324840434406584">"የድምፅ ፍለጋ"</string>
<string name="accessibility_all_apps_button" msgid="2603132375383800483">"መተግበሪያዎች"</string>
<string name="accessibility_delete_button" msgid="6466114477993744621">"አስወግድ"</string>
<string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"ዝማኔ አራግፍ"</string>
@@ -96,7 +95,7 @@
<string name="migration_cling_copy_apps" msgid="946331230090919440">"አዶዎችን ይቅዱ"</string>
<string name="migration_cling_use_default" msgid="2626475813981258626">"እንደ አዲስ ይጀምሩ"</string>
<string name="workspace_cling_title" msgid="5626202359865825661">"ቦታዎን ያደራጁ"</string>
- <string name="workspace_cling_move_item" msgid="528201129978005352">"የግድግዳ ወረቀት፣ ምግብሮችን እና ቅንብሮችን ለማቀናበር ጀርባውን ይንኩ እና ይያዙት።"</string>
+ <string name="workspace_cling_move_item" msgid="528201129978005352">"ልጣፍ ፣ ምግብሮችን እና ቅንብሮችን ለማቀናበር ጀርባውን ይንኩ እና ይያዙት።"</string>
<string name="workspace_cling_longpress_title" msgid="9173998993909018310">"የግድግዳ ወረቀቶች፣ ንዑስ ፕሮግራሞች እና ቅንብሮች"</string>
<string name="workspace_cling_longpress_description" msgid="4119994475505235248">"ለማበጀት ጀርባውን ነክተው ይያዙት"</string>
<string name="workspace_cling_longpress_dismiss" msgid="368660286867640874">"ገባኝ"</string>
diff --git a/res/values-ar-land/strings.xml b/res/values-ar-land/strings.xml
deleted file mode 100644
index b976926f0..000000000
--- a/res/values-ar-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="delete_target_label" msgid="4155210680095864979"></string>
- <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
- <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml
index 8b6aa025c..592be5841 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -24,12 +24,13 @@
<string name="uid_name" msgid="7820867637514617527">"‏تطبيقات Android الأساسية"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
<string name="activity_not_found" msgid="8071924732094499514">"لم يتم تثبيت التطبيق."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"التطبيق ليس متاحًا"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"تم تعطيل التطبيق الذي تم تنزيله في الوضع الآمن"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"الأدوات معطلة في الوضع الآمن"</string>
<string name="widgets_tab_label" msgid="2921133187116603919">"الأدوات"</string>
<string name="widget_adder" msgid="3201040140710381657">"الأدوات"</string>
<string name="toggle_weight_watcher" msgid="5645299835184636119">"عرض الذاكرة"</string>
<string name="long_press_widget_to_add" msgid="7699152356777458215">"المس مع الاستمرار لاختيار إحدى الأدوات."</string>
- <string name="market" msgid="2619650989819296998">"تسوق"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="external_drop_widget_error" msgid="3165821058322217155">"تعذر إسقاط العنصر على هذه الشاشة الرئيسية."</string>
<string name="external_drop_widget_pick_title" msgid="3486317258037690630">"اختيار أداة لإنشائها"</string>
@@ -57,8 +58,6 @@
<string name="delete_target_label" msgid="1822697352535677073">"إزالة"</string>
<string name="delete_target_uninstall_label" msgid="5100785476250872595">"إزالة"</string>
<string name="info_target_label" msgid="8053346143994679532">"معلومات عن التطبيق"</string>
- <string name="accessibility_search_button" msgid="1628520399424565142">"بحث"</string>
- <string name="accessibility_voice_search_button" msgid="4637324840434406584">"البحث الصوتي"</string>
<string name="accessibility_all_apps_button" msgid="2603132375383800483">"التطبيقات"</string>
<string name="accessibility_delete_button" msgid="6466114477993744621">"إزالة"</string>
<string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"إزالة التحديث"</string>
diff --git a/res/values-bg-land/strings.xml b/res/values-bg-land/strings.xml
deleted file mode 100644
index b976926f0..000000000
--- a/res/values-bg-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="delete_target_label" msgid="4155210680095864979"></string>
- <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
- <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml
index dcd193050..3f710db30 100644
--- a/res/values-bg/strings.xml
+++ b/res/values-bg/strings.xml
@@ -24,12 +24,13 @@
<string name="uid_name" msgid="7820867637514617527">"Основни приложения на Android"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
<string name="activity_not_found" msgid="8071924732094499514">"Приложението не е инсталирано."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"Приложението не е налично"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Изтегленото приложение е деактивирано в безопасния режим"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"Приспособленията са деактивирани в безопасния режим"</string>
<string name="widgets_tab_label" msgid="2921133187116603919">"Приспособления"</string>
<string name="widget_adder" msgid="3201040140710381657">"Приспособления"</string>
<string name="toggle_weight_watcher" msgid="5645299835184636119">"Показване на паметта"</string>
<string name="long_press_widget_to_add" msgid="7699152356777458215">"Докоснете и задръжте за избор на приспособление."</string>
- <string name="market" msgid="2619650989819296998">"Пазаруване"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="external_drop_widget_error" msgid="3165821058322217155">"Не можа да се премести на този начален екран."</string>
<string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Избор на приспособл. за създаване"</string>
@@ -57,8 +58,6 @@
<string name="delete_target_label" msgid="1822697352535677073">"Премахване"</string>
<string name="delete_target_uninstall_label" msgid="5100785476250872595">"Деинсталиране"</string>
<string name="info_target_label" msgid="8053346143994679532">"Информация за приложението"</string>
- <string name="accessibility_search_button" msgid="1628520399424565142">"Търсене"</string>
- <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Гласово търсене"</string>
<string name="accessibility_all_apps_button" msgid="2603132375383800483">"Приложения"</string>
<string name="accessibility_delete_button" msgid="6466114477993744621">"Премахване"</string>
<string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Деинст. на актуализацията"</string>
diff --git a/res/values-bn-rBD/strings.xml b/res/values-bn-rBD/strings.xml
index f60f1c507..143420103 100644
--- a/res/values-bn-rBD/strings.xml
+++ b/res/values-bn-rBD/strings.xml
@@ -24,12 +24,13 @@
<string name="uid_name" msgid="7820867637514617527">"Android প্রাথমিক অ্যাপ্লিকেশানগুলি"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
<string name="activity_not_found" msgid="8071924732094499514">"অ্যাপ্লিকেশান ইনস্টল করা নেই৷"</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"অ্যাপ্লিকেশান অনুপলব্ধ"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"ডাউনলোড করা অ্যাপ্লিকেশান নিরাপদ মোডে অক্ষম রয়েছে"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"সুরক্ষিত মোডে উইজেট নিষ্ক্রিয় থাকে"</string>
<string name="widgets_tab_label" msgid="2921133187116603919">"উইজেটগুলি"</string>
<string name="widget_adder" msgid="3201040140710381657">"উইজেটগুলি"</string>
<string name="toggle_weight_watcher" msgid="5645299835184636119">"মেম দেখান"</string>
<string name="long_press_widget_to_add" msgid="7699152356777458215">"একটি উইজেট তুলতে তা স্পর্শ করে ধরে রাখুন৷"</string>
- <string name="market" msgid="2619650989819296998">"দোকান"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="external_drop_widget_error" msgid="3165821058322217155">"এই হোম স্ক্রীনে আইটেম রাখা যায়নি৷"</string>
<string name="external_drop_widget_pick_title" msgid="3486317258037690630">"তৈরি করেতে উইজেট চয়ন করুন"</string>
@@ -57,8 +58,6 @@
<string name="delete_target_label" msgid="1822697352535677073">"সরান"</string>
<string name="delete_target_uninstall_label" msgid="5100785476250872595">"আনইনস্টল করুন"</string>
<string name="info_target_label" msgid="8053346143994679532">"অ্যাপ্লিকেশানের তথ্য"</string>
- <string name="accessibility_search_button" msgid="1628520399424565142">"অনুসন্ধান করুন"</string>
- <string name="accessibility_voice_search_button" msgid="4637324840434406584">"ভয়েস অনুসন্ধান"</string>
<string name="accessibility_all_apps_button" msgid="2603132375383800483">"অ্যাপ্লিকেশানগুলি"</string>
<string name="accessibility_delete_button" msgid="6466114477993744621">"সরান"</string>
<string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"আপডেট আনইনস্টল করুন"</string>
@@ -77,6 +76,7 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"হোম সেটিংস এবং শর্টকাটগুলি লেখে"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"হোমে অ্যাপ্লিকেশানটিকে সেটিংস এবং শর্টকাটগুলি পরিবর্তন করতে দেয়৷"</string>
<string name="gadget_error_text" msgid="6081085226050792095">"উইজেট লোড হতে সমস্যা হয়েছে"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"সেটআপ"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"এটি একটি সিস্টেম অ্যাপ্লিকেশান এবং আনইনস্টল করা যাবে না৷"</string>
<string name="dream_name" msgid="1530253749244328964">"রকেট লঞ্চার"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"নামবিহীন ফোল্ডার"</string>
@@ -96,6 +96,9 @@
<string name="migration_cling_use_default" msgid="2626475813981258626">"নতুন করে শুরু করুন"</string>
<string name="workspace_cling_title" msgid="5626202359865825661">"আপনার স্থান সংগঠিত করুন"</string>
<string name="workspace_cling_move_item" msgid="528201129978005352">"ওয়ালপেপার, উইজেট এবং সেটিংস পরিচালনা করতে পটভূমি স্পর্শ করে ধরে রাখুন৷"</string>
+ <string name="workspace_cling_longpress_title" msgid="9173998993909018310">"ওয়ালপেপার, উইজেট এবং সেটিংস"</string>
+ <string name="workspace_cling_longpress_description" msgid="4119994475505235248">"কাস্টমাইজ করার জন্য পটভূমি স্পর্শ করে ধরে থাকুন"</string>
+ <string name="workspace_cling_longpress_dismiss" msgid="368660286867640874">"বুঝেছি"</string>
<string name="folder_cling_title" msgid="3894908818693254164">"এখানে একটি ফোল্ডার আছে"</string>
<string name="folder_cling_create_folder" msgid="6158215559475836131">"এটির মতো একটি তৈরি করতে, একটি অ্যাপ্লিকেশান স্পর্শ করে ধরে রাখুন, এবং তারপরে এটিকে অন্য একটির উপরে সরিয়ে নিয়ে যান৷"</string>
<string name="cling_dismiss" msgid="8962359497601507581">"ঠিক আছে"</string>
diff --git a/res/values-ca-land/strings.xml b/res/values-ca-land/strings.xml
deleted file mode 100644
index b976926f0..000000000
--- a/res/values-ca-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="delete_target_label" msgid="4155210680095864979"></string>
- <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
- <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml
index 6d1023545..89e582a81 100644
--- a/res/values-ca/strings.xml
+++ b/res/values-ca/strings.xml
@@ -24,12 +24,13 @@
<string name="uid_name" msgid="7820867637514617527">"Aplicacions principals d\'Android"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
<string name="activity_not_found" msgid="8071924732094499514">"L\'aplicació no s\'ha instal·lat."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"L\'aplicació no està disponible."</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"L\'aplicació que has baixat està desactivada al mode segur."</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"En Mode segur, els widgets estan desactivats."</string>
<string name="widgets_tab_label" msgid="2921133187116603919">"Widgets"</string>
<string name="widget_adder" msgid="3201040140710381657">"Widgets"</string>
<string name="toggle_weight_watcher" msgid="5645299835184636119">"Mostra la memòria"</string>
<string name="long_press_widget_to_add" msgid="7699152356777458215">"Mantén premut un widget per triar-lo."</string>
- <string name="market" msgid="2619650989819296998">"Compra"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="external_drop_widget_error" msgid="3165821058322217155">"No s\'ha pogut deixar anar l\'element a Inici."</string>
<string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Tria el widget que vulguis crear"</string>
@@ -57,8 +58,6 @@
<string name="delete_target_label" msgid="1822697352535677073">"Suprimeix"</string>
<string name="delete_target_uninstall_label" msgid="5100785476250872595">"Desinstal·la"</string>
<string name="info_target_label" msgid="8053346143994679532">"Informació de l\'aplicació"</string>
- <string name="accessibility_search_button" msgid="1628520399424565142">"Cerca"</string>
- <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Cerca per veu"</string>
<string name="accessibility_all_apps_button" msgid="2603132375383800483">"Aplicacions"</string>
<string name="accessibility_delete_button" msgid="6466114477993744621">"Suprimeix"</string>
<string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Desinstal·la l\'actualització"</string>
diff --git a/res/values-cs-land/strings.xml b/res/values-cs-land/strings.xml
deleted file mode 100644
index b976926f0..000000000
--- a/res/values-cs-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="delete_target_label" msgid="4155210680095864979"></string>
- <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
- <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index f729a460e..69ec22c41 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -24,12 +24,13 @@
<string name="uid_name" msgid="7820867637514617527">"Android Core Apps"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
<string name="activity_not_found" msgid="8071924732094499514">"Aplikace není nainstalována."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"Aplikace není k dispozici."</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Stažená aplikace je v nouzovém režimu zakázána"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"V Bezpečném režimu jsou widgety zakázány."</string>
<string name="widgets_tab_label" msgid="2921133187116603919">"Widgety"</string>
<string name="widget_adder" msgid="3201040140710381657">"Widgety"</string>
<string name="toggle_weight_watcher" msgid="5645299835184636119">"Zobrazit Mem"</string>
<string name="long_press_widget_to_add" msgid="7699152356777458215">"Widget vyberete dotykem a podržením."</string>
- <string name="market" msgid="2619650989819296998">"Obchod"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="external_drop_widget_error" msgid="3165821058322217155">"Na tuto plochu položku nelze přesunout."</string>
<string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Vyberte widget k vytvoření"</string>
@@ -57,8 +58,6 @@
<string name="delete_target_label" msgid="1822697352535677073">"Odstranit"</string>
<string name="delete_target_uninstall_label" msgid="5100785476250872595">"Odinstalovat"</string>
<string name="info_target_label" msgid="8053346143994679532">"Informace o aplikaci"</string>
- <string name="accessibility_search_button" msgid="1628520399424565142">"Hledat"</string>
- <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Hlasové vyhledávání"</string>
<string name="accessibility_all_apps_button" msgid="2603132375383800483">"Aplikace"</string>
<string name="accessibility_delete_button" msgid="6466114477993744621">"Odstranit"</string>
<string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Odinstalovat aktualizaci"</string>
diff --git a/res/values-da-land/strings.xml b/res/values-da-land/strings.xml
deleted file mode 100644
index b976926f0..000000000
--- a/res/values-da-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="delete_target_label" msgid="4155210680095864979"></string>
- <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
- <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index 85159b2e1..5fa6aa6b6 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -24,12 +24,13 @@
<string name="uid_name" msgid="7820867637514617527">"Kerneapps i Android"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
<string name="activity_not_found" msgid="8071924732094499514">"Appen er ikke installeret."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"Appen er ikke tilgængelig"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Downloadet app er deaktiveret i sikker tilstand"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"Widgets er deaktiveret i Beskyttet tilstand"</string>
<string name="widgets_tab_label" msgid="2921133187116603919">"Widgets"</string>
<string name="widget_adder" msgid="3201040140710381657">"Widgets"</string>
<string name="toggle_weight_watcher" msgid="5645299835184636119">"Vis Mem"</string>
<string name="long_press_widget_to_add" msgid="7699152356777458215">"Tryk på en widget, og hold den nede for at vælge."</string>
- <string name="market" msgid="2619650989819296998">"Køb i Google Play Butik"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="external_drop_widget_error" msgid="3165821058322217155">"Elementet kunne ikke trækkes til startskærmen."</string>
<string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Vælg den widget, du vil oprette"</string>
@@ -57,8 +58,6 @@
<string name="delete_target_label" msgid="1822697352535677073">"Fjern"</string>
<string name="delete_target_uninstall_label" msgid="5100785476250872595">"Afinstaller"</string>
<string name="info_target_label" msgid="8053346143994679532">"Oplysninger om appen"</string>
- <string name="accessibility_search_button" msgid="1628520399424565142">"Søg"</string>
- <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Stemmesøgning"</string>
<string name="accessibility_all_apps_button" msgid="2603132375383800483">"Apps"</string>
<string name="accessibility_delete_button" msgid="6466114477993744621">"Fjern"</string>
<string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Afinstaller opdatering"</string>
diff --git a/res/values-de-land/strings.xml b/res/values-de-land/strings.xml
deleted file mode 100644
index b976926f0..000000000
--- a/res/values-de-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="delete_target_label" msgid="4155210680095864979"></string>
- <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
- <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index 698a25413..059983ecf 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -24,12 +24,13 @@
<string name="uid_name" msgid="7820867637514617527">"Android Core Apps"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
<string name="activity_not_found" msgid="8071924732094499514">"App ist nicht installiert."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"App nicht verfügbar"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Heruntergeladene App im abgesicherten Modus deaktiviert"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"Widgets im abgesicherten Modus deaktiviert"</string>
<string name="widgets_tab_label" msgid="2921133187116603919">"Widgets"</string>
<string name="widget_adder" msgid="3201040140710381657">"Widgets"</string>
<string name="toggle_weight_watcher" msgid="5645299835184636119">"Speicher anzeigen"</string>
<string name="long_press_widget_to_add" msgid="7699152356777458215">"Zum Hinzufügen Widget berühren und halten"</string>
- <string name="market" msgid="2619650989819296998">"Einkaufen"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="external_drop_widget_error" msgid="3165821058322217155">"Element wurde nicht auf diesem Startbildschirm abgelegt."</string>
<string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Widget zum Erstellen auswählen"</string>
@@ -57,8 +58,6 @@
<string name="delete_target_label" msgid="1822697352535677073">"Entfernen"</string>
<string name="delete_target_uninstall_label" msgid="5100785476250872595">"Deinstallieren"</string>
<string name="info_target_label" msgid="8053346143994679532">"App-Info"</string>
- <string name="accessibility_search_button" msgid="1628520399424565142">"Suchen"</string>
- <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Sprachsuche"</string>
<string name="accessibility_all_apps_button" msgid="2603132375383800483">"Apps"</string>
<string name="accessibility_delete_button" msgid="6466114477993744621">"Entfernen"</string>
<string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Update deinstallieren"</string>
diff --git a/res/values-el-land/strings.xml b/res/values-el-land/strings.xml
deleted file mode 100644
index b976926f0..000000000
--- a/res/values-el-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="delete_target_label" msgid="4155210680095864979"></string>
- <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
- <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml
index 3eec27d4f..12f0dfef1 100644
--- a/res/values-el/strings.xml
+++ b/res/values-el/strings.xml
@@ -24,12 +24,13 @@
<string name="uid_name" msgid="7820867637514617527">"Βασικές εφαρμογές Android"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
<string name="activity_not_found" msgid="8071924732094499514">"Η εφαρμογή δεν έχει εγκατασταθεί."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"Η εφαρμογή δεν είναι διαθέσιμη"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Η λήψη εφαρμογών απενεργοποήθηκε στην Ασφαλή λειτουργία"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"Τα γραφικά στοιχεία απενεργοποιήθηκαν στην ασφαλή λειτουργία"</string>
<string name="widgets_tab_label" msgid="2921133187116603919">"Γραφικά στοιχεία"</string>
<string name="widget_adder" msgid="3201040140710381657">"Γραφικά στοιχεία"</string>
<string name="toggle_weight_watcher" msgid="5645299835184636119">"Εμφάνιση Mem"</string>
<string name="long_press_widget_to_add" msgid="7699152356777458215">"Αγγίξτε παρατεταμένα για να πάρετε ένα γραφ.στοιχ."</string>
- <string name="market" msgid="2619650989819296998">"Αγορά"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="external_drop_widget_error" msgid="3165821058322217155">"Αδυναμία τοποθέτησης στοιχείου στην Αρχική οθόνη."</string>
<string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Επιλ. γραφ. στοιχείο για δημιουργία"</string>
@@ -57,8 +58,6 @@
<string name="delete_target_label" msgid="1822697352535677073">"Κατάργηση"</string>
<string name="delete_target_uninstall_label" msgid="5100785476250872595">"Κατάργηση εγκατάστασης"</string>
<string name="info_target_label" msgid="8053346143994679532">"Πληροφορίες εφαρμογής"</string>
- <string name="accessibility_search_button" msgid="1628520399424565142">"Αναζήτηση"</string>
- <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Φωνητική αναζήτηση"</string>
<string name="accessibility_all_apps_button" msgid="2603132375383800483">"Εφαρμογές"</string>
<string name="accessibility_delete_button" msgid="6466114477993744621">"Κατάργηση"</string>
<string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Κατάργηση εγκατάστασης ενημέρωσης"</string>
diff --git a/res/values-en-rGB-land/strings.xml b/res/values-en-rGB-land/strings.xml
deleted file mode 100644
index b976926f0..000000000
--- a/res/values-en-rGB-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="delete_target_label" msgid="4155210680095864979"></string>
- <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
- <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml
index 615e5c90d..0d004fef5 100644
--- a/res/values-en-rGB/strings.xml
+++ b/res/values-en-rGB/strings.xml
@@ -24,12 +24,13 @@
<string name="uid_name" msgid="7820867637514617527">"Android Core Apps"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
<string name="activity_not_found" msgid="8071924732094499514">"App isn\'t installed."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"App isn\'t available"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Downloaded app disabled in Safe mode"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"Widgets disabled in Safe mode"</string>
<string name="widgets_tab_label" msgid="2921133187116603919">"Widgets"</string>
<string name="widget_adder" msgid="3201040140710381657">"Widgets"</string>
<string name="toggle_weight_watcher" msgid="5645299835184636119">"Show Mem"</string>
<string name="long_press_widget_to_add" msgid="7699152356777458215">"Touch &amp; hold to pick up a widget."</string>
- <string name="market" msgid="2619650989819296998">"Shop"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="external_drop_widget_error" msgid="3165821058322217155">"Couldn\'t drop item on this Home screen."</string>
<string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Choose widget to create"</string>
@@ -57,8 +58,6 @@
<string name="delete_target_label" msgid="1822697352535677073">"Remove"</string>
<string name="delete_target_uninstall_label" msgid="5100785476250872595">"Uninstall"</string>
<string name="info_target_label" msgid="8053346143994679532">"App info"</string>
- <string name="accessibility_search_button" msgid="1628520399424565142">"Search"</string>
- <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Voice Search"</string>
<string name="accessibility_all_apps_button" msgid="2603132375383800483">"Apps"</string>
<string name="accessibility_delete_button" msgid="6466114477993744621">"Remove"</string>
<string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Uninstall update"</string>
diff --git a/res/values-en-rIN/strings.xml b/res/values-en-rIN/strings.xml
index 615e5c90d..0d004fef5 100644
--- a/res/values-en-rIN/strings.xml
+++ b/res/values-en-rIN/strings.xml
@@ -24,12 +24,13 @@
<string name="uid_name" msgid="7820867637514617527">"Android Core Apps"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
<string name="activity_not_found" msgid="8071924732094499514">"App isn\'t installed."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"App isn\'t available"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Downloaded app disabled in Safe mode"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"Widgets disabled in Safe mode"</string>
<string name="widgets_tab_label" msgid="2921133187116603919">"Widgets"</string>
<string name="widget_adder" msgid="3201040140710381657">"Widgets"</string>
<string name="toggle_weight_watcher" msgid="5645299835184636119">"Show Mem"</string>
<string name="long_press_widget_to_add" msgid="7699152356777458215">"Touch &amp; hold to pick up a widget."</string>
- <string name="market" msgid="2619650989819296998">"Shop"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="external_drop_widget_error" msgid="3165821058322217155">"Couldn\'t drop item on this Home screen."</string>
<string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Choose widget to create"</string>
@@ -57,8 +58,6 @@
<string name="delete_target_label" msgid="1822697352535677073">"Remove"</string>
<string name="delete_target_uninstall_label" msgid="5100785476250872595">"Uninstall"</string>
<string name="info_target_label" msgid="8053346143994679532">"App info"</string>
- <string name="accessibility_search_button" msgid="1628520399424565142">"Search"</string>
- <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Voice Search"</string>
<string name="accessibility_all_apps_button" msgid="2603132375383800483">"Apps"</string>
<string name="accessibility_delete_button" msgid="6466114477993744621">"Remove"</string>
<string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Uninstall update"</string>
diff --git a/res/values-es-land/strings.xml b/res/values-es-land/strings.xml
deleted file mode 100644
index b976926f0..000000000
--- a/res/values-es-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="delete_target_label" msgid="4155210680095864979"></string>
- <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
- <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-es-rUS-land/strings.xml b/res/values-es-rUS-land/strings.xml
deleted file mode 100644
index b976926f0..000000000
--- a/res/values-es-rUS-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="delete_target_label" msgid="4155210680095864979"></string>
- <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
- <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
index 31afa3e52..4408080e2 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -24,12 +24,13 @@
<string name="uid_name" msgid="7820867637514617527">"Aplicaciones básicas de Android"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
<string name="activity_not_found" msgid="8071924732094499514">"No se instaló la aplicación."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"La aplicación no está disponible."</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Aplicación descargada inhabilitada en modo seguro"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"Widgets inhabilitados en modo seguro"</string>
<string name="widgets_tab_label" msgid="2921133187116603919">"Widgets"</string>
<string name="widget_adder" msgid="3201040140710381657">"Widgets"</string>
<string name="toggle_weight_watcher" msgid="5645299835184636119">"Mostrar memoria"</string>
<string name="long_press_widget_to_add" msgid="7699152356777458215">"Mantén presionado el widget que desees elegir."</string>
- <string name="market" msgid="2619650989819296998">"Comprar"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="external_drop_widget_error" msgid="3165821058322217155">"Error al soltar elemento en la pantalla principal"</string>
<string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Elegir los widgets para crear"</string>
@@ -57,8 +58,6 @@
<string name="delete_target_label" msgid="1822697352535677073">"Eliminar"</string>
<string name="delete_target_uninstall_label" msgid="5100785476250872595">"Desinstalar"</string>
<string name="info_target_label" msgid="8053346143994679532">"Información de la aplicación"</string>
- <string name="accessibility_search_button" msgid="1628520399424565142">"Buscar"</string>
- <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Búsqueda por voz"</string>
<string name="accessibility_all_apps_button" msgid="2603132375383800483">"Aplicaciones"</string>
<string name="accessibility_delete_button" msgid="6466114477993744621">"Eliminar"</string>
<string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Desinstalar actualización"</string>
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index 4e9141208..898d0eaa5 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -24,12 +24,13 @@
<string name="uid_name" msgid="7820867637514617527">"Aplicaciones básicas de Android"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
<string name="activity_not_found" msgid="8071924732094499514">"La aplicación no está instalada."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"La aplicación no está disponible"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Aplicación descargada inhabilitada en modo seguro"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"Widgets inhabilitados en modo seguro"</string>
<string name="widgets_tab_label" msgid="2921133187116603919">"Widgets"</string>
<string name="widget_adder" msgid="3201040140710381657">"Widgets"</string>
<string name="toggle_weight_watcher" msgid="5645299835184636119">"Mostrar memoria"</string>
<string name="long_press_widget_to_add" msgid="7699152356777458215">"Mantén pulsado el widget que quieras seleccionar."</string>
- <string name="market" msgid="2619650989819296998">"Tienda"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="external_drop_widget_error" msgid="3165821058322217155">"Error al arrastrar elemento a pantalla de inicio."</string>
<string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Selecciona widget a añadir"</string>
@@ -57,8 +58,6 @@
<string name="delete_target_label" msgid="1822697352535677073">"Eliminar"</string>
<string name="delete_target_uninstall_label" msgid="5100785476250872595">"Desinstalar"</string>
<string name="info_target_label" msgid="8053346143994679532">"Información de la aplicación"</string>
- <string name="accessibility_search_button" msgid="1628520399424565142">"Buscar"</string>
- <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Búsqueda por voz"</string>
<string name="accessibility_all_apps_button" msgid="2603132375383800483">"Aplicaciones"</string>
<string name="accessibility_delete_button" msgid="6466114477993744621">"Eliminar"</string>
<string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Desinstalar actualización"</string>
diff --git a/res/values-et-rEE/strings.xml b/res/values-et-rEE/strings.xml
index fa352a1a3..76b20aba7 100644
--- a/res/values-et-rEE/strings.xml
+++ b/res/values-et-rEE/strings.xml
@@ -24,12 +24,13 @@
<string name="uid_name" msgid="7820867637514617527">"Androidi tuumrakendused"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
<string name="activity_not_found" msgid="8071924732094499514">"Rakendus pole installitud."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"Rakendus ei ole saadaval"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Allalaetud rakendus on turvarežiimis keelatud"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"Turvarežiimis on vidinad keelatud"</string>
<string name="widgets_tab_label" msgid="2921133187116603919">"Vidinad"</string>
<string name="widget_adder" msgid="3201040140710381657">"Vidinad"</string>
<string name="toggle_weight_watcher" msgid="5645299835184636119">"Mälu kuvamine"</string>
<string name="long_press_widget_to_add" msgid="7699152356777458215">"Vidina valimiseks vajutage ja hoidke seda all."</string>
- <string name="market" msgid="2619650989819296998">"Pood"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="external_drop_widget_error" msgid="3165821058322217155">"Üksust ei saanud sellele avaekraanile tuua."</string>
<string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Valige loomiseks vidin"</string>
@@ -57,8 +58,6 @@
<string name="delete_target_label" msgid="1822697352535677073">"Eemalda"</string>
<string name="delete_target_uninstall_label" msgid="5100785476250872595">"Desinstalli"</string>
<string name="info_target_label" msgid="8053346143994679532">"Rakenduse teave"</string>
- <string name="accessibility_search_button" msgid="1628520399424565142">"Otsing"</string>
- <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Häälotsing"</string>
<string name="accessibility_all_apps_button" msgid="2603132375383800483">"Rakendused"</string>
<string name="accessibility_delete_button" msgid="6466114477993744621">"Eemalda"</string>
<string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Desinstalli värskendus"</string>
diff --git a/res/values-eu-rES/strings.xml b/res/values-eu-rES/strings.xml
index 4a4c959f4..e02479c0e 100644
--- a/res/values-eu-rES/strings.xml
+++ b/res/values-eu-rES/strings.xml
@@ -24,12 +24,13 @@
<string name="uid_name" msgid="7820867637514617527">"Android-en nukleoko aplikazioak"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
<string name="activity_not_found" msgid="8071924732094499514">"Aplikazioa instalatu gabe dago."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"Ez dago erabilgarri aplikazioa"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Deskargatutako aplikazioa modu seguruan desgaitu da"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"Widgetak desgaitu egin dira modu seguruan"</string>
<string name="widgets_tab_label" msgid="2921133187116603919">"Widgetak"</string>
<string name="widget_adder" msgid="3201040140710381657">"Widgetak"</string>
<string name="toggle_weight_watcher" msgid="5645299835184636119">"Erakutsi memoria"</string>
<string name="long_press_widget_to_add" msgid="7699152356777458215">"Eduki ukituta widgeta aukeratzeko."</string>
- <string name="market" msgid="2619650989819296998">"Denda"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="external_drop_widget_error" msgid="3165821058322217155">"Ezin izan da elementua hasierako pantailan jaregin."</string>
<string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Aukeratu sortu beharreko widgeta"</string>
@@ -57,8 +58,6 @@
<string name="delete_target_label" msgid="1822697352535677073">"Kendu"</string>
<string name="delete_target_uninstall_label" msgid="5100785476250872595">"Desinstalatu"</string>
<string name="info_target_label" msgid="8053346143994679532">"Aplikazioaren informazioa"</string>
- <string name="accessibility_search_button" msgid="1628520399424565142">"Bilaketa"</string>
- <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Ahots bidezko bilaketa"</string>
<string name="accessibility_all_apps_button" msgid="2603132375383800483">"Aplikazioak"</string>
<string name="accessibility_delete_button" msgid="6466114477993744621">"Kendu"</string>
<string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Desinstalatu eguneratzea"</string>
@@ -77,6 +76,7 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"Idatzi hasierako ezarpenak eta lasterbideak"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Hasierako pantailako ezarpenak eta lasterbideak aldatzea baimentzen die aplikazioei."</string>
<string name="gadget_error_text" msgid="6081085226050792095">"Arazo bat izan da widgeta kargatzean"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Konfigurazioa"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Sistema-aplikazioa da hau eta ezin da desinstalatu."</string>
<string name="dream_name" msgid="1530253749244328964">"Rocket Launcher"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"Izenik gabeko karpeta"</string>
@@ -86,7 +86,7 @@
<string name="apps_customize_apps_scroll_format" msgid="370005296147130238">"%1$d/%2$d aplikazio-orria"</string>
<string name="apps_customize_widgets_scroll_format" msgid="3106209519974971521">"%1$d/%2$d widget-orria"</string>
<string name="first_run_cling_title" msgid="2459738000155917941">"Ongi etorri"</string>
- <string name="first_run_cling_description" msgid="6447072552696253358">"Senti zaitez etxean bezala."</string>
+ <string name="first_run_cling_description" msgid="6447072552696253358">"Pertsonalizatu hasierako pantaila nahieran."</string>
<string name="first_run_cling_custom_content_hint" msgid="6090628589029352439"></string>
<string name="first_run_cling_search_bar_hint" msgid="5909062802402452582"></string>
<string name="first_run_cling_create_screens_hint" msgid="6950729526680114157">"Sortu pantaila gehiago aplikazioak eta karpetak ezartzeko"</string>
@@ -96,6 +96,9 @@
<string name="migration_cling_use_default" msgid="2626475813981258626">"HASI HUTSETIK"</string>
<string name="workspace_cling_title" msgid="5626202359865825661">"Antolatu zure txokoa"</string>
<string name="workspace_cling_move_item" msgid="528201129978005352">"Eduki ukituta atzeko planoa horma-paperak, widgetak eta ezarpenak kudeatzeko."</string>
+ <string name="workspace_cling_longpress_title" msgid="9173998993909018310">"Horma-paperak, widgetak eta ezarpenak"</string>
+ <string name="workspace_cling_longpress_description" msgid="4119994475505235248">"Pertsonalizatzeko, eduki ukituta atzeko planoa"</string>
+ <string name="workspace_cling_longpress_dismiss" msgid="368660286867640874">"ADOS"</string>
<string name="folder_cling_title" msgid="3894908818693254164">"Hortxe duzu karpeta"</string>
<string name="folder_cling_create_folder" msgid="6158215559475836131">"Horrelako bat sortzeko, eduki ukituta aplikazio bat eta eraman beste baten gainera."</string>
<string name="cling_dismiss" msgid="8962359497601507581">"Ados"</string>
diff --git a/res/values-fa-land/strings.xml b/res/values-fa-land/strings.xml
deleted file mode 100644
index b976926f0..000000000
--- a/res/values-fa-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="delete_target_label" msgid="4155210680095864979"></string>
- <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
- <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml
index 13f40e223..924cccf75 100644
--- a/res/values-fa/strings.xml
+++ b/res/values-fa/strings.xml
@@ -24,12 +24,13 @@
<string name="uid_name" msgid="7820867637514617527">"‏برنامه‌های Android Core"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
<string name="activity_not_found" msgid="8071924732094499514">"برنامه نصب نشده است."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"برنامه در دسترس نیست"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"برنامه دانلود شده در حالت ایمن غیرفعال شد"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"ابزارک‌ها در حالت ایمن غیرفعال هستند"</string>
<string name="widgets_tab_label" msgid="2921133187116603919">"ابزارک‌ها"</string>
<string name="widget_adder" msgid="3201040140710381657">"ابزارک‌ها"</string>
<string name="toggle_weight_watcher" msgid="5645299835184636119">"‏نمایش Mem"</string>
<string name="long_press_widget_to_add" msgid="7699152356777458215">"برای انتخاب ابزارک لمس کنید و نگه دارید."</string>
- <string name="market" msgid="2619650989819296998">"فروشگاه"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="external_drop_widget_error" msgid="3165821058322217155">"این مورد را نمی‌توان در این صفحه اصلی رها کرد."</string>
<string name="external_drop_widget_pick_title" msgid="3486317258037690630">"انتخاب ابزارکی که باید ایجاد شود"</string>
@@ -57,8 +58,6 @@
<string name="delete_target_label" msgid="1822697352535677073">"حذف"</string>
<string name="delete_target_uninstall_label" msgid="5100785476250872595">"حذف نصب"</string>
<string name="info_target_label" msgid="8053346143994679532">"اطلاعات برنامه"</string>
- <string name="accessibility_search_button" msgid="1628520399424565142">"جستجو"</string>
- <string name="accessibility_voice_search_button" msgid="4637324840434406584">"جستجوی شفاهی"</string>
<string name="accessibility_all_apps_button" msgid="2603132375383800483">"برنامه‌ها"</string>
<string name="accessibility_delete_button" msgid="6466114477993744621">"حذف"</string>
<string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"حذف نصب به‌روزرسانی"</string>
diff --git a/res/values-fi-land/strings.xml b/res/values-fi-land/strings.xml
deleted file mode 100644
index b976926f0..000000000
--- a/res/values-fi-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="delete_target_label" msgid="4155210680095864979"></string>
- <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
- <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml
index 3990a163c..a5da03f43 100644
--- a/res/values-fi/strings.xml
+++ b/res/values-fi/strings.xml
@@ -24,12 +24,13 @@
<string name="uid_name" msgid="7820867637514617527">"Androidin ydinsovellukset"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
<string name="activity_not_found" msgid="8071924732094499514">"Sovellusta ei ole asennettu."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"Sovellus ei ole käytettävissä"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Ladattu sovellus poistettiin käytöstä suojatussa tilassa"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"Widgetit poistettu käytöstä vikasietotilassa"</string>
<string name="widgets_tab_label" msgid="2921133187116603919">"Widgetit"</string>
<string name="widget_adder" msgid="3201040140710381657">"Widgetit"</string>
<string name="toggle_weight_watcher" msgid="5645299835184636119">"Näytä muisti"</string>
<string name="long_press_widget_to_add" msgid="7699152356777458215">"Valitse widget painamalla sitä pitkään."</string>
- <string name="market" msgid="2619650989819296998">"Kauppa"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="external_drop_widget_error" msgid="3165821058322217155">"Kohteen lisääminen tähän aloitusruutuun epäonnistui."</string>
<string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Valitse luotava widget"</string>
@@ -57,8 +58,6 @@
<string name="delete_target_label" msgid="1822697352535677073">"Poista"</string>
<string name="delete_target_uninstall_label" msgid="5100785476250872595">"Poista"</string>
<string name="info_target_label" msgid="8053346143994679532">"Sovelluksen tiedot"</string>
- <string name="accessibility_search_button" msgid="1628520399424565142">"Haku"</string>
- <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Puhehaku"</string>
<string name="accessibility_all_apps_button" msgid="2603132375383800483">"Sovellukset"</string>
<string name="accessibility_delete_button" msgid="6466114477993744621">"Poista"</string>
<string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Poista päivitys"</string>
diff --git a/res/values-fr-land/strings.xml b/res/values-fr-land/strings.xml
deleted file mode 100644
index b976926f0..000000000
--- a/res/values-fr-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="delete_target_label" msgid="4155210680095864979"></string>
- <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
- <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-fr-rCA/strings.xml b/res/values-fr-rCA/strings.xml
index f42835014..62a2b894e 100644
--- a/res/values-fr-rCA/strings.xml
+++ b/res/values-fr-rCA/strings.xml
@@ -24,12 +24,13 @@
<string name="uid_name" msgid="7820867637514617527">"Applications de base Android"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
<string name="activity_not_found" msgid="8071924732094499514">"L\'application n\'est pas installée."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"Application indisponible"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"L\'application téléchargée est désactivée en mode sécurisé."</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"Widgets désactivés en mode sans échec"</string>
<string name="widgets_tab_label" msgid="2921133187116603919">"Widgets"</string>
<string name="widget_adder" msgid="3201040140710381657">"Widgets"</string>
<string name="toggle_weight_watcher" msgid="5645299835184636119">"Afficher la mémoire"</string>
<string name="long_press_widget_to_add" msgid="7699152356777458215">"Maintenez un doigt sur le widget pour l\'ajouter."</string>
- <string name="market" msgid="2619650989819296998">"Magasiner"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="external_drop_widget_error" msgid="3165821058322217155">"Imposs. de déposer l\'élément sur l\'écran d\'accueil"</string>
<string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Sélectionnez le widget à créer"</string>
@@ -57,8 +58,6 @@
<string name="delete_target_label" msgid="1822697352535677073">"Supprimer"</string>
<string name="delete_target_uninstall_label" msgid="5100785476250872595">"Désinstaller"</string>
<string name="info_target_label" msgid="8053346143994679532">"Détails de l\'application"</string>
- <string name="accessibility_search_button" msgid="1628520399424565142">"Rechercher"</string>
- <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Recherche vocale"</string>
<string name="accessibility_all_apps_button" msgid="2603132375383800483">"Applications"</string>
<string name="accessibility_delete_button" msgid="6466114477993744621">"Supprimer"</string>
<string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Désinstaller la mise à jour"</string>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index 31448f18b..d23b6a492 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -24,12 +24,13 @@
<string name="uid_name" msgid="7820867637514617527">"Applications de base Android"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
<string name="activity_not_found" msgid="8071924732094499514">"L\'application n\'est pas installée."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"Application indisponible"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"L\'application téléchargée est désactivée en mode sécurisé."</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"Les widgets sont désactivés en mode sécurisé."</string>
<string name="widgets_tab_label" msgid="2921133187116603919">"Widgets"</string>
<string name="widget_adder" msgid="3201040140710381657">"Widgets"</string>
<string name="toggle_weight_watcher" msgid="5645299835184636119">"Afficher la mémoire"</string>
<string name="long_press_widget_to_add" msgid="7699152356777458215">"App. de manière prolongée pour sélectionner widget."</string>
- <string name="market" msgid="2619650989819296998">"Boutique"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d x %2$d"</string>
<string name="external_drop_widget_error" msgid="3165821058322217155">"Impossible de déposer élément sur écran d\'accueil."</string>
<string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Sélectionner le widget à créer"</string>
@@ -57,8 +58,6 @@
<string name="delete_target_label" msgid="1822697352535677073">"Supprimer"</string>
<string name="delete_target_uninstall_label" msgid="5100785476250872595">"Désinstaller"</string>
<string name="info_target_label" msgid="8053346143994679532">"Informations sur l\'application"</string>
- <string name="accessibility_search_button" msgid="1628520399424565142">"Rechercher"</string>
- <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Recherche vocale"</string>
<string name="accessibility_all_apps_button" msgid="2603132375383800483">"Applications"</string>
<string name="accessibility_delete_button" msgid="6466114477993744621">"Supprimer"</string>
<string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Désinstaller la mise à jour"</string>
diff --git a/res/values-gl-rES/strings.xml b/res/values-gl-rES/strings.xml
index c053b07fe..96a53dc09 100644
--- a/res/values-gl-rES/strings.xml
+++ b/res/values-gl-rES/strings.xml
@@ -24,12 +24,13 @@
<string name="uid_name" msgid="7820867637514617527">"Aplicacións básicas de Android"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
<string name="activity_not_found" msgid="8071924732094499514">"A aplicación non está instalada"</string>
- <string name="safemode_shortcut_error" msgid="9160126848219158407">"Desactivouse a aplicación descargada no modo seguro"</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"A aplicación non está dispoñible"</string>
+ <string name="safemode_shortcut_error" msgid="9160126848219158407">"A aplicación que descargaches está desactivada no modo seguro"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"Os widgets están desactivados no modo seguro"</string>
<string name="widgets_tab_label" msgid="2921133187116603919">"Widgets"</string>
<string name="widget_adder" msgid="3201040140710381657">"Widgets"</string>
<string name="toggle_weight_watcher" msgid="5645299835184636119">"Mostrar memoria"</string>
<string name="long_press_widget_to_add" msgid="7699152356777458215">"Mantén premido un widget para seleccionalo."</string>
- <string name="market" msgid="2619650989819296998">"Tenda"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="external_drop_widget_error" msgid="3165821058322217155">"Non se puido engadir á pantalla de inicio."</string>
<string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Escolle o widget que queiras crear"</string>
@@ -57,8 +58,6 @@
<string name="delete_target_label" msgid="1822697352535677073">"Eliminar"</string>
<string name="delete_target_uninstall_label" msgid="5100785476250872595">"Desinstalar"</string>
<string name="info_target_label" msgid="8053346143994679532">"Información da aplicación"</string>
- <string name="accessibility_search_button" msgid="1628520399424565142">"Buscar"</string>
- <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Busca de voz"</string>
<string name="accessibility_all_apps_button" msgid="2603132375383800483">"Aplicacións"</string>
<string name="accessibility_delete_button" msgid="6466114477993744621">"Eliminar"</string>
<string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Desinstalar actualización"</string>
@@ -77,6 +76,7 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"modificar a configuración e os atallos da pantalla de inicio"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Permite a unha aplicación cambiar a configuración e os atallos da pantalla de inicio."</string>
<string name="gadget_error_text" msgid="6081085226050792095">"Produciuse un problema ao cargar o widget"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Configuración"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Esta aplicación é do sistema e non se pode desinstalar."</string>
<string name="dream_name" msgid="1530253749244328964">"Lanzacohetes"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"Cartafol sen nome"</string>
@@ -96,6 +96,9 @@
<string name="migration_cling_use_default" msgid="2626475813981258626">"COMEZAR DE CERO"</string>
<string name="workspace_cling_title" msgid="5626202359865825661">"Organiza o espazo"</string>
<string name="workspace_cling_move_item" msgid="528201129978005352">"Mantén premido o fondo para xestionar o fondo de pantalla e máis."</string>
+ <string name="workspace_cling_longpress_title" msgid="9173998993909018310">"Fondos pantalla, widgets e configuración"</string>
+ <string name="workspace_cling_longpress_description" msgid="4119994475505235248">"Mantén tocado o segundo plano para personalizar"</string>
+ <string name="workspace_cling_longpress_dismiss" msgid="368660286867640874">"DE ACORDO"</string>
<string name="folder_cling_title" msgid="3894908818693254164">"Isto é un cartafol"</string>
<string name="folder_cling_create_folder" msgid="6158215559475836131">"Para crear un igual, mantén premida a aplicación e móvea sobre outra."</string>
<string name="cling_dismiss" msgid="8962359497601507581">"Aceptar"</string>
diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml
index 9058b7895..937248921 100644
--- a/res/values-hi/strings.xml
+++ b/res/values-hi/strings.xml
@@ -24,23 +24,24 @@
<string name="uid_name" msgid="7820867637514617527">"Android के मुख्य ऐप्लिकेशन"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
<string name="activity_not_found" msgid="8071924732094499514">"एप्‍लिकेशन इंस्‍टॉल नहीं है."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"ऐप्स उपलब्ध नहीं है"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"डाउनलोड किए गए ऐप्स सुरक्षित मोड में अक्षम है"</string>
- <string name="widgets_tab_label" msgid="2921133187116603919">"विजेट"</string>
- <string name="widget_adder" msgid="3201040140710381657">"विजेट"</string>
- <string name="toggle_weight_watcher" msgid="5645299835184636119">"स्मृति दिखाएं"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"विजेट सुरक्षित मोड में अक्षम हैं"</string>
+ <string name="widgets_tab_label" msgid="2921133187116603919">"शॉर्टकट"</string>
+ <string name="widget_adder" msgid="3201040140710381657">"शॉर्टकट"</string>
+ <string name="toggle_weight_watcher" msgid="5645299835184636119">"मेमोरी दिखाएं"</string>
<string name="long_press_widget_to_add" msgid="7699152356777458215">"विजेट को चुनने के लिए स्‍पर्श करके रखें."</string>
- <string name="market" msgid="2619650989819296998">"खरीदारी करें"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="external_drop_widget_error" msgid="3165821058322217155">"आइटम को इस होम स्‍क्रीन पर नहीं छोड़ा जा सका."</string>
<string name="external_drop_widget_pick_title" msgid="3486317258037690630">"बनाने के लिए विजेट चुनें"</string>
<string name="rename_folder_label" msgid="3727762225964550653">"फ़ोल्‍डर का नाम"</string>
<string name="rename_folder_title" msgid="3771389277707820891">"फ़ोल्‍डर का नाम बदलें"</string>
<string name="rename_action" msgid="5559600076028658757">"ठीक"</string>
- <string name="cancel_action" msgid="7009134900002915310">"रद्द करें"</string>
+ <string name="cancel_action" msgid="7009134900002915310">"रहने दें"</string>
<string name="menu_item_add_item" msgid="1264911265836810421">"होम स्‍क्रीन में जोड़ें"</string>
<string name="group_applications" msgid="3797214114206693605">"ऐप्लिकेशन"</string>
<string name="group_shortcuts" msgid="6012256992764410535">"शॉर्टकट"</string>
- <string name="group_widgets" msgid="1569030723286851002">"विजेट"</string>
+ <string name="group_widgets" msgid="1569030723286851002">"शॉर्टकट"</string>
<string name="completely_out_of_space" msgid="6106288382070760318">"आपकी होम स्‍क्रीन पर स्थान शेष नहीं है."</string>
<string name="out_of_space" msgid="4691004494942118364">"इस होम स्‍क्रीन पर स्थान शेष नहीं है."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"पसंदीदा ट्रे में और स्थान नहीं है"</string>
@@ -57,8 +58,6 @@
<string name="delete_target_label" msgid="1822697352535677073">"निकालें"</string>
<string name="delete_target_uninstall_label" msgid="5100785476250872595">"अनइंस्टॉल करें"</string>
<string name="info_target_label" msgid="8053346143994679532">"ऐप्लिकेशन की जानकारी"</string>
- <string name="accessibility_search_button" msgid="1628520399424565142">"खोजें"</string>
- <string name="accessibility_voice_search_button" msgid="4637324840434406584">"बोलकर खोजें"</string>
<string name="accessibility_all_apps_button" msgid="2603132375383800483">"ऐप्लिकेशन"</string>
<string name="accessibility_delete_button" msgid="6466114477993744621">"निकालें"</string>
<string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"अपडेट अनइंस्‍टॉल करें"</string>
@@ -85,7 +84,7 @@
<string name="default_scroll_format" msgid="7475544710230993317">"पृष्ठ %2$d में से %1$d"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"होम स्क्रीन %2$d में से %1$d"</string>
<string name="apps_customize_apps_scroll_format" msgid="370005296147130238">"ऐप्लिकेशन पृष्ठ %2$d में से %1$d"</string>
- <string name="apps_customize_widgets_scroll_format" msgid="3106209519974971521">"विजेट पृष्ठ %2$d में से %1$d"</string>
+ <string name="apps_customize_widgets_scroll_format" msgid="3106209519974971521">"शॉर्टकट %2$d में से %1$d"</string>
<string name="first_run_cling_title" msgid="2459738000155917941">"स्वागत है"</string>
<string name="first_run_cling_description" msgid="6447072552696253358">"जैसा चाहें वैसा उपयोग करें."</string>
<string name="first_run_cling_custom_content_hint" msgid="6090628589029352439"></string>
@@ -96,8 +95,8 @@
<string name="migration_cling_copy_apps" msgid="946331230090919440">"आइकन की प्रतिलिपि बनाएं"</string>
<string name="migration_cling_use_default" msgid="2626475813981258626">"फिर से शुरू करें"</string>
<string name="workspace_cling_title" msgid="5626202359865825661">"अपने स्थान को व्यवस्थित करें"</string>
- <string name="workspace_cling_move_item" msgid="528201129978005352">"वॉलपेपर, विजेट और सेटिंग प्रबंधित करने के लिए पृष्ठभूमि को स्पर्श करके रखें."</string>
- <string name="workspace_cling_longpress_title" msgid="9173998993909018310">"वॉलपेपर, विजेट और सेटिंग"</string>
+ <string name="workspace_cling_move_item" msgid="528201129978005352">"वॉलपेपर, शॉर्टकट और सेटिंग प्रबंधित करने के लिए पृष्ठभूमि को स्पर्श करके रखें."</string>
+ <string name="workspace_cling_longpress_title" msgid="9173998993909018310">"वॉलपेपर, शॉर्टकट और सेटिंग"</string>
<string name="workspace_cling_longpress_description" msgid="4119994475505235248">"पृष्ठभूमि कस्टमाइज़ करने के लिए स्पर्श करके रखें"</string>
<string name="workspace_cling_longpress_dismiss" msgid="368660286867640874">"समझ लिया"</string>
<string name="folder_cling_title" msgid="3894908818693254164">"यहां एक फ़ोल्डर है"</string>
@@ -109,7 +108,7 @@
<string name="folder_closed" msgid="4100806530910930934">"फ़ोल्डर बंद किया गया"</string>
<string name="folder_renamed" msgid="1794088362165669656">"फ़ोल्डर का नाम बदलकर <xliff:g id="NAME">%1$s</xliff:g> किया गया"</string>
<string name="folder_name_format" msgid="6629239338071103179">"फ़ोल्डर: <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"विजेट"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"शॉर्टकट"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"वॉलपेपर"</string>
<string name="settings_button_text" msgid="8119458837558863227">"सेटिंग"</string>
<string name="package_state_enqueued" msgid="6227252464303085641">"प्रतीक्षा में"</string>
diff --git a/res/values-hr-land/strings.xml b/res/values-hr-land/strings.xml
deleted file mode 100644
index b976926f0..000000000
--- a/res/values-hr-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="delete_target_label" msgid="4155210680095864979"></string>
- <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
- <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml
index c881077b1..702b474ff 100644
--- a/res/values-hr/strings.xml
+++ b/res/values-hr/strings.xml
@@ -24,12 +24,13 @@
<string name="uid_name" msgid="7820867637514617527">"Matične aplikacije za Android"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
<string name="activity_not_found" msgid="8071924732094499514">"Aplikacija nije instalirana."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"Aplikacija nije dostupna"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Preuzeta aplikacija onemogućena je u Sigurnom načinu rada"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"Widgeti su onemogućeni u Sigurnom načinu rada"</string>
<string name="widgets_tab_label" msgid="2921133187116603919">"Widgeti"</string>
<string name="widget_adder" msgid="3201040140710381657">"Widgeti"</string>
<string name="toggle_weight_watcher" msgid="5645299835184636119">"Prikaži mem"</string>
<string name="long_press_widget_to_add" msgid="7699152356777458215">"Dodirnite i držite kako biste podigli widget."</string>
- <string name="market" msgid="2619650989819296998">"Kupi"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="external_drop_widget_error" msgid="3165821058322217155">"Stavka nije ispuštena na ovaj početni zaslon."</string>
<string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Odabir widgeta za stvaranje"</string>
@@ -57,8 +58,6 @@
<string name="delete_target_label" msgid="1822697352535677073">"Ukloni"</string>
<string name="delete_target_uninstall_label" msgid="5100785476250872595">"Deinstaliraj"</string>
<string name="info_target_label" msgid="8053346143994679532">"Informacije o aplikaciji"</string>
- <string name="accessibility_search_button" msgid="1628520399424565142">"Pretraži"</string>
- <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Glasovno pretraživanje"</string>
<string name="accessibility_all_apps_button" msgid="2603132375383800483">"Aplikacije"</string>
<string name="accessibility_delete_button" msgid="6466114477993744621">"Ukloni"</string>
<string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Deinstalacija ažuriranja"</string>
diff --git a/res/values-hu-land/strings.xml b/res/values-hu-land/strings.xml
deleted file mode 100644
index b976926f0..000000000
--- a/res/values-hu-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="delete_target_label" msgid="4155210680095864979"></string>
- <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
- <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml
index 08d309558..513548a2a 100644
--- a/res/values-hu/strings.xml
+++ b/res/values-hu/strings.xml
@@ -24,12 +24,13 @@
<string name="uid_name" msgid="7820867637514617527">"Alap Android-alkalmazások"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
<string name="activity_not_found" msgid="8071924732094499514">"Az alkalmazás nincs telepítve."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"Az alkalmazás nem érhető el"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"A letöltött alkalmazás Csökkentett módban ki van kapcsolva"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"A modulok ki vannak kapcsolva Csökkentett módban"</string>
<string name="widgets_tab_label" msgid="2921133187116603919">"Modulok"</string>
<string name="widget_adder" msgid="3201040140710381657">"Modulok"</string>
<string name="toggle_weight_watcher" msgid="5645299835184636119">"Mem. megjelenítése"</string>
<string name="long_press_widget_to_add" msgid="7699152356777458215">"Modul felvételéhez érintse meg, és tartsa lenyomva"</string>
- <string name="market" msgid="2619650989819296998">"Vásárlás"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="external_drop_widget_error" msgid="3165821058322217155">"Nem lehet elemeket dobni erre a kezdőképernyőre."</string>
<string name="external_drop_widget_pick_title" msgid="3486317258037690630">"A létrehozáshoz válasszon modult"</string>
@@ -57,8 +58,6 @@
<string name="delete_target_label" msgid="1822697352535677073">"Eltávolítás"</string>
<string name="delete_target_uninstall_label" msgid="5100785476250872595">"Eltávolítás"</string>
<string name="info_target_label" msgid="8053346143994679532">"Alkalmazásinformáció"</string>
- <string name="accessibility_search_button" msgid="1628520399424565142">"Keresés"</string>
- <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Hangalapú keresés"</string>
<string name="accessibility_all_apps_button" msgid="2603132375383800483">"Alkalmazások"</string>
<string name="accessibility_delete_button" msgid="6466114477993744621">"Eltávolítás"</string>
<string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Eltávolítja a frissítést"</string>
diff --git a/res/values-hy-rAM/strings.xml b/res/values-hy-rAM/strings.xml
index 4ec39c88c..940c14bf2 100644
--- a/res/values-hy-rAM/strings.xml
+++ b/res/values-hy-rAM/strings.xml
@@ -24,12 +24,13 @@
<string name="uid_name" msgid="7820867637514617527">"Android Core Apps"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
<string name="activity_not_found" msgid="8071924732094499514">"Ծրագիրը տեղադրված չէ:"</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"Հավելվածը հասանելի չէ"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Ներբեռնված ծրագիրն անջատված է Անվտանգ ռեժիմում"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"Վիջեթներն անջատված են անվտանգ ռեժիմում"</string>
<string name="widgets_tab_label" msgid="2921133187116603919">"Վիջեթներ"</string>
<string name="widget_adder" msgid="3201040140710381657">"Վիջեթներ"</string>
<string name="toggle_weight_watcher" msgid="5645299835184636119">"Ցուցադրել մեմը"</string>
<string name="long_press_widget_to_add" msgid="7699152356777458215">"Հպեք և պահեք՝ վիջեթն ընտրելու համար:"</string>
- <string name="market" msgid="2619650989819296998">"Խանութ"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="external_drop_widget_error" msgid="3165821058322217155">"Հնարավոր չէ տեղադրել տարրն այս հիմնական էկրանին:"</string>
<string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Ստեղծելու համար ընտրեք վիջեթը"</string>
@@ -57,8 +58,6 @@
<string name="delete_target_label" msgid="1822697352535677073">"Հեռացնել"</string>
<string name="delete_target_uninstall_label" msgid="5100785476250872595">"Ապատեղադրել"</string>
<string name="info_target_label" msgid="8053346143994679532">"Ծրագրի տեղեկություններ"</string>
- <string name="accessibility_search_button" msgid="1628520399424565142">"Որոնել"</string>
- <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Ձայնային որոնում"</string>
<string name="accessibility_all_apps_button" msgid="2603132375383800483">"Ծրագրեր"</string>
<string name="accessibility_delete_button" msgid="6466114477993744621">"Հեռացնել"</string>
<string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Ապատեղադրել թարմացումը"</string>
diff --git a/res/values-in-land/strings.xml b/res/values-in-land/strings.xml
deleted file mode 100644
index b976926f0..000000000
--- a/res/values-in-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="delete_target_label" msgid="4155210680095864979"></string>
- <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
- <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml
index 137e3cc7d..b0c5d139d 100644
--- a/res/values-in/strings.xml
+++ b/res/values-in/strings.xml
@@ -24,12 +24,13 @@
<string name="uid_name" msgid="7820867637514617527">"Aplikasi Inti Android"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
<string name="activity_not_found" msgid="8071924732094499514">"Aplikasi tidak dipasang."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"Aplikasi tidak tersedia"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Aplikasi yang diunduh dinonaktifkan dalam mode Aman"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"Widget dinonaktifkan dalam mode Aman"</string>
<string name="widgets_tab_label" msgid="2921133187116603919">"Widget"</string>
<string name="widget_adder" msgid="3201040140710381657">"Widget"</string>
<string name="toggle_weight_watcher" msgid="5645299835184636119">"Tampilkan Memori"</string>
<string name="long_press_widget_to_add" msgid="7699152356777458215">"Sentuh lama untuk memilih widget."</string>
- <string name="market" msgid="2619650989819296998">"Belanja"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="external_drop_widget_error" msgid="3165821058322217155">"Tidak dapat melepas item ke layar Utama ini."</string>
<string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Pilih widget untuk membuat"</string>
@@ -57,8 +58,6 @@
<string name="delete_target_label" msgid="1822697352535677073">"Hapus"</string>
<string name="delete_target_uninstall_label" msgid="5100785476250872595">"Copot pemasangan"</string>
<string name="info_target_label" msgid="8053346143994679532">"Info aplikasi"</string>
- <string name="accessibility_search_button" msgid="1628520399424565142">"Telusuri"</string>
- <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Penelusuran Suara"</string>
<string name="accessibility_all_apps_button" msgid="2603132375383800483">"Aplikasi"</string>
<string name="accessibility_delete_button" msgid="6466114477993744621">"Hapus"</string>
<string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Copot pemasangan pembaruan"</string>
diff --git a/res/values-is-rIS/strings.xml b/res/values-is-rIS/strings.xml
index 71f0edea9..a3fa0bc52 100644
--- a/res/values-is-rIS/strings.xml
+++ b/res/values-is-rIS/strings.xml
@@ -24,12 +24,13 @@
<string name="uid_name" msgid="7820867637514617527">"Kjarnaforrit Android"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
<string name="activity_not_found" msgid="8071924732094499514">"Forritið er ekki uppsett."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"Forritið er ekki í boði"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Sótt forrit er óvirkt í öryggisstillingu"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"Græjur eru óvirkar í öruggri stillingu"</string>
<string name="widgets_tab_label" msgid="2921133187116603919">"Græjur"</string>
<string name="widget_adder" msgid="3201040140710381657">"Græjur"</string>
<string name="toggle_weight_watcher" msgid="5645299835184636119">"Sýna minni"</string>
<string name="long_press_widget_to_add" msgid="7699152356777458215">"Haltu fingri á græju til að grípa hana."</string>
- <string name="market" msgid="2619650989819296998">"Verslun"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="external_drop_widget_error" msgid="3165821058322217155">"Ekki er hægt að sleppa atriði á þennan heimaskjá."</string>
<string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Veldu græju til að búa til"</string>
@@ -57,8 +58,6 @@
<string name="delete_target_label" msgid="1822697352535677073">"Fjarlægja"</string>
<string name="delete_target_uninstall_label" msgid="5100785476250872595">"Eyða"</string>
<string name="info_target_label" msgid="8053346143994679532">"Upplýsingar um forrit"</string>
- <string name="accessibility_search_button" msgid="1628520399424565142">"Leita"</string>
- <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Raddleit"</string>
<string name="accessibility_all_apps_button" msgid="2603132375383800483">"Forrit"</string>
<string name="accessibility_delete_button" msgid="6466114477993744621">"Fjarlægja"</string>
<string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Fjarlægja uppfærslu"</string>
@@ -77,6 +76,7 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"skrifa stillingar og flýtileiðir heimaskjás"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Leyfir forriti að breyta stillingum og flýtileiðum heimaskjás."</string>
<string name="gadget_error_text" msgid="6081085226050792095">"Vandamál við að hlaða græju"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Uppsetning"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Þetta er kerfisforrit sem ekki er hægt að fjarlægja."</string>
<string name="dream_name" msgid="1530253749244328964">"Eldflaugapallur"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"Ónefnd mappa"</string>
@@ -96,6 +96,9 @@
<string name="migration_cling_use_default" msgid="2626475813981258626">"BYRJA UPP Á NÝTT"</string>
<string name="workspace_cling_title" msgid="5626202359865825661">"Settu hlutina á sína staði"</string>
<string name="workspace_cling_move_item" msgid="528201129978005352">"Haltu inni á bakgrunni til að stjórna veggfóðri, græjum og stillingum."</string>
+ <string name="workspace_cling_longpress_title" msgid="9173998993909018310">"Veggfóður, græjur og stillingar"</string>
+ <string name="workspace_cling_longpress_description" msgid="4119994475505235248">"Haltu fingri á bakgrunninum til að sérsníða hann"</string>
+ <string name="workspace_cling_longpress_dismiss" msgid="368660286867640874">"ÉG SKIL"</string>
<string name="folder_cling_title" msgid="3894908818693254164">"Hér er mappa"</string>
<string name="folder_cling_create_folder" msgid="6158215559475836131">"Til að búa til svona skaltu draga forrit yfir á annað forrit."</string>
<string name="cling_dismiss" msgid="8962359497601507581">"Í lagi"</string>
diff --git a/res/values-it-land/strings.xml b/res/values-it-land/strings.xml
deleted file mode 100644
index b976926f0..000000000
--- a/res/values-it-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="delete_target_label" msgid="4155210680095864979"></string>
- <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
- <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index b01b25174..d78d0326d 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -24,12 +24,13 @@
<string name="uid_name" msgid="7820867637514617527">"Applicazioni di base Android"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
<string name="activity_not_found" msgid="8071924732094499514">"App non installata."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"App non disponibile"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"L\'app scaricata è stata disattivata in modalità provvisoria"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"Widget disabilitati in modalità provvisoria"</string>
<string name="widgets_tab_label" msgid="2921133187116603919">"Widget"</string>
<string name="widget_adder" msgid="3201040140710381657">"Widget"</string>
<string name="toggle_weight_watcher" msgid="5645299835184636119">"Mostra Mem"</string>
<string name="long_press_widget_to_add" msgid="7699152356777458215">"Tocca e tieni premuto per scegliere un widget."</string>
- <string name="market" msgid="2619650989819296998">"Acquista"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="external_drop_widget_error" msgid="3165821058322217155">"Rilascio elemento in schermata Home non riuscito."</string>
<string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Scegli il widget da creare"</string>
@@ -57,8 +58,6 @@
<string name="delete_target_label" msgid="1822697352535677073">"Rimuovi"</string>
<string name="delete_target_uninstall_label" msgid="5100785476250872595">"Disinstalla"</string>
<string name="info_target_label" msgid="8053346143994679532">"Informazioni app"</string>
- <string name="accessibility_search_button" msgid="1628520399424565142">"Cerca"</string>
- <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Ricerca vocale"</string>
<string name="accessibility_all_apps_button" msgid="2603132375383800483">"App"</string>
<string name="accessibility_delete_button" msgid="6466114477993744621">"Rimuovi"</string>
<string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Disinstalla aggiornamento"</string>
diff --git a/res/values-iw-land/strings.xml b/res/values-iw-land/strings.xml
deleted file mode 100644
index b976926f0..000000000
--- a/res/values-iw-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="delete_target_label" msgid="4155210680095864979"></string>
- <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
- <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml
index 6318207ff..61fb53efa 100644
--- a/res/values-iw/strings.xml
+++ b/res/values-iw/strings.xml
@@ -24,12 +24,13 @@
<string name="uid_name" msgid="7820867637514617527">"‏אפליקציות הליבה של Android"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
<string name="activity_not_found" msgid="8071924732094499514">"האפליקציה לא מותקנת."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"האפליקציה אינה זמינה"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"אפליקציה שהורדת הושבתה במצב בטוח"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"ווידג\'טים מושבתים במצב בטוח"</string>
<string name="widgets_tab_label" msgid="2921133187116603919">"רכיבי ווידג\'ט"</string>
<string name="widget_adder" msgid="3201040140710381657">"רכיבי ווידג\'ט"</string>
<string name="toggle_weight_watcher" msgid="5645299835184636119">"הצג זכרון"</string>
<string name="long_press_widget_to_add" msgid="7699152356777458215">"גע נגיעה רציפה בווידג\'ט כדי לבחור בו."</string>
- <string name="market" msgid="2619650989819296998">"קנה"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="external_drop_widget_error" msgid="3165821058322217155">"לא ניתן היה לשחרר את הפריט במסך דף הבית הזה."</string>
<string name="external_drop_widget_pick_title" msgid="3486317258037690630">"בחר ווידג\'ט ליצירה"</string>
@@ -57,8 +58,6 @@
<string name="delete_target_label" msgid="1822697352535677073">"הסר"</string>
<string name="delete_target_uninstall_label" msgid="5100785476250872595">"הסר התקנה"</string>
<string name="info_target_label" msgid="8053346143994679532">"פרטי אפליקציה"</string>
- <string name="accessibility_search_button" msgid="1628520399424565142">"חפש"</string>
- <string name="accessibility_voice_search_button" msgid="4637324840434406584">"חיפוש קולי"</string>
<string name="accessibility_all_apps_button" msgid="2603132375383800483">"אפליקציות"</string>
<string name="accessibility_delete_button" msgid="6466114477993744621">"הסר"</string>
<string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"הסר את התקנת העדכון"</string>
diff --git a/res/values-ja-land/strings.xml b/res/values-ja-land/strings.xml
deleted file mode 100644
index b976926f0..000000000
--- a/res/values-ja-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="delete_target_label" msgid="4155210680095864979"></string>
- <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
- <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index 232845af0..ec872b8a9 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -24,12 +24,13 @@
<string name="uid_name" msgid="7820867637514617527">"Android Core Apps"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
<string name="activity_not_found" msgid="8071924732094499514">"このアプリはインストールされていません。"</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"このアプリは使用できません"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"ダウンロードしたアプリは、セーフモードでは無効です"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"セーフモードではウィジェットは無効です"</string>
<string name="widgets_tab_label" msgid="2921133187116603919">"ウィジェット"</string>
<string name="widget_adder" msgid="3201040140710381657">"ウィジェット"</string>
<string name="toggle_weight_watcher" msgid="5645299835184636119">"メモリーを表示"</string>
<string name="long_press_widget_to_add" msgid="7699152356777458215">"ウィジェットを追加するには押し続けます。"</string>
- <string name="market" msgid="2619650989819296998">"ショップ"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$dx%2$d"</string>
<string name="external_drop_widget_error" msgid="3165821058322217155">"このホーム画面にアイテムをドロップできませんでした"</string>
<string name="external_drop_widget_pick_title" msgid="3486317258037690630">"作成するウィジェットの選択"</string>
@@ -57,8 +58,6 @@
<string name="delete_target_label" msgid="1822697352535677073">"削除"</string>
<string name="delete_target_uninstall_label" msgid="5100785476250872595">"アンインストール"</string>
<string name="info_target_label" msgid="8053346143994679532">"アプリ情報"</string>
- <string name="accessibility_search_button" msgid="1628520399424565142">"検索"</string>
- <string name="accessibility_voice_search_button" msgid="4637324840434406584">"音声検索"</string>
<string name="accessibility_all_apps_button" msgid="2603132375383800483">"アプリ"</string>
<string name="accessibility_delete_button" msgid="6466114477993744621">"削除"</string>
<string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"更新をアンインストール"</string>
diff --git a/res/values-ka-rGE/strings.xml b/res/values-ka-rGE/strings.xml
index 2fb51f541..b96d3d267 100644
--- a/res/values-ka-rGE/strings.xml
+++ b/res/values-ka-rGE/strings.xml
@@ -24,12 +24,13 @@
<string name="uid_name" msgid="7820867637514617527">"Android-ის ბირთვის აპები"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
<string name="activity_not_found" msgid="8071924732094499514">"აპი არ არის დაყენებული."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"აპი მიუწვდომელია"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"უსაფრთხო რეჟიმში ჩამოტვირთული აპი გაუქმებულია"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"უსაფრთხო რეჟიმში ვიჯეტი გამორთულია"</string>
<string name="widgets_tab_label" msgid="2921133187116603919">"ვიჯეტები"</string>
<string name="widget_adder" msgid="3201040140710381657">"ვიჯეტები"</string>
<string name="toggle_weight_watcher" msgid="5645299835184636119">"Mem-ის ჩვენება"</string>
<string name="long_press_widget_to_add" msgid="7699152356777458215">"შეეხეთ და დააყოვნეთ ვიჯეტის ასარჩევად."</string>
- <string name="market" msgid="2619650989819296998">"მაღაზია"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="external_drop_widget_error" msgid="3165821058322217155">"ერთეულის მთავარ ეკრანზე ჩაგდება ვერ მოხერხდა."</string>
<string name="external_drop_widget_pick_title" msgid="3486317258037690630">"აირჩიეთ ვიჯეტი შესაქმნელად"</string>
@@ -57,8 +58,6 @@
<string name="delete_target_label" msgid="1822697352535677073">"წაშლა"</string>
<string name="delete_target_uninstall_label" msgid="5100785476250872595">"დეინსტალაცია"</string>
<string name="info_target_label" msgid="8053346143994679532">"აპის შესახებ"</string>
- <string name="accessibility_search_button" msgid="1628520399424565142">"ძიება"</string>
- <string name="accessibility_voice_search_button" msgid="4637324840434406584">"ხმოვანი ძიება"</string>
<string name="accessibility_all_apps_button" msgid="2603132375383800483">"აპები"</string>
<string name="accessibility_delete_button" msgid="6466114477993744621">"წაშლა"</string>
<string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"განახლების დეინსტალაცია"</string>
diff --git a/res/values-kk-rKZ/strings.xml b/res/values-kk-rKZ/strings.xml
index 288129ace..c5b5a62f6 100644
--- a/res/values-kk-rKZ/strings.xml
+++ b/res/values-kk-rKZ/strings.xml
@@ -24,13 +24,13 @@
<string name="uid_name" msgid="7820867637514617527">"Android Core қолданбалары"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
<string name="activity_not_found" msgid="8071924732094499514">"Қолданба орнатылмаған."</string>
- <!-- no translation found for safemode_shortcut_error (9160126848219158407) -->
- <skip />
+ <string name="activity_not_available" msgid="7456344436509528827">"Қолданба қол жетімді емес"</string>
+ <string name="safemode_shortcut_error" msgid="9160126848219158407">"Жүктелген қолданба қауіпсіз режимде өшірілген"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"Қауіпсіз режимде виджеттер өшіріледі"</string>
<string name="widgets_tab_label" msgid="2921133187116603919">"Виджеттер"</string>
<string name="widget_adder" msgid="3201040140710381657">"Виджеттер"</string>
<string name="toggle_weight_watcher" msgid="5645299835184636119">"Жадты көрсету"</string>
<string name="long_press_widget_to_add" msgid="7699152356777458215">"Виджетті таңдау үшін түртіп, мықтап ұстаңыз."</string>
- <string name="market" msgid="2619650989819296998">"Дүкен"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="external_drop_widget_error" msgid="3165821058322217155">"Элементті осы Негізгі Экранға тастау орындалмады."</string>
<string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Жасақтау үшін виджет таңдау"</string>
@@ -58,8 +58,6 @@
<string name="delete_target_label" msgid="1822697352535677073">"Алып тастау"</string>
<string name="delete_target_uninstall_label" msgid="5100785476250872595">"Алмау"</string>
<string name="info_target_label" msgid="8053346143994679532">"Қолданба ақпары"</string>
- <string name="accessibility_search_button" msgid="1628520399424565142">"Іздеу"</string>
- <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Дауыс арқылы іздеу"</string>
<string name="accessibility_all_apps_button" msgid="2603132375383800483">"Қолданбалар"</string>
<string name="accessibility_delete_button" msgid="6466114477993744621">"Алып тастау"</string>
<string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Жаңартуды алмау"</string>
@@ -78,6 +76,7 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"Негізгі экран параметрлері мен төте пернелерін жазу"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Қолданбаға Негізгі экрандағы параметрлер мен төте пернелерді өзгерту мүмкіндігін береді."</string>
<string name="gadget_error_text" msgid="6081085226050792095">"Виджетті жүктеу барысында мәселе орын алды"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Орнату"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Бұл жүйе қолданбасы, сондықтан оны алу мүмкін емес."</string>
<string name="dream_name" msgid="1530253749244328964">"Rocket Launcher"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"Атауы жоқ қалта"</string>
@@ -97,6 +96,9 @@
<string name="migration_cling_use_default" msgid="2626475813981258626">"ЖАҢАДАН БАСТАУ"</string>
<string name="workspace_cling_title" msgid="5626202359865825661">"Кеңістікті реттеу"</string>
<string name="workspace_cling_move_item" msgid="528201129978005352">"Артқы фонды, виджеттерді және параметрлерді басқару үшін артқы шебін түртіп, мықтап ұстаңыз."</string>
+ <string name="workspace_cling_longpress_title" msgid="9173998993909018310">"Тұсқағаздар, виджеттер және параметрлер"</string>
+ <string name="workspace_cling_longpress_description" msgid="4119994475505235248">"Теңшеу үшін фонды түртіп, ұстап тұрыңыз"</string>
+ <string name="workspace_cling_longpress_dismiss" msgid="368660286867640874">"ТҮСІНДІМ"</string>
<string name="folder_cling_title" msgid="3894908818693254164">"Міне, қалта."</string>
<string name="folder_cling_create_folder" msgid="6158215559475836131">"Осы сияқты қалта жасау үшін, қолданбаны түртіп, мықтап ұстаңыз, одан кейін екіншісінің үстінен жылжытыңыз."</string>
<string name="cling_dismiss" msgid="8962359497601507581">"Жарайды"</string>
diff --git a/res/values-km-rKH/strings.xml b/res/values-km-rKH/strings.xml
index bcd606000..3a1c82dcc 100644
--- a/res/values-km-rKH/strings.xml
+++ b/res/values-km-rKH/strings.xml
@@ -24,12 +24,13 @@
<string name="uid_name" msgid="7820867637514617527">"កម្មវិធី​​សំខាន់​ៗ​របស់ Android"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
<string name="activity_not_found" msgid="8071924732094499514">"មិន​បាន​ដំឡើង​កម្មវិធី។"</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"មិន​មាន​កម្មវិធី"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"បាន​បិទ​កម្មវិធី​ដែល​បាន​ទាញ​យក​ក្នុង​របៀប​សុវត្ថិភាព"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"បាន​បិទ​ធាតុ​ក្រាហ្វិក​ក្នុង​របៀប​សុវត្ថិភាព"</string>
<string name="widgets_tab_label" msgid="2921133187116603919">"ធាតុ​ក្រាហ្វិក"</string>
<string name="widget_adder" msgid="3201040140710381657">"ធាតុ​ក្រាហ្វិក"</string>
<string name="toggle_weight_watcher" msgid="5645299835184636119">"បង្ហាញ​ Mem"</string>
<string name="long_press_widget_to_add" msgid="7699152356777458215">"ប៉ះ &amp; សង្កត់ ដើម្បី​ជ្រើស​ធាតុ​ក្រាហ្វិក។"</string>
- <string name="market" msgid="2619650989819296998">"ហាងទំនិញ"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="external_drop_widget_error" msgid="3165821058322217155">"មិន​អាច​ទម្លាក់​ធាតុ​លើ​អេក្រង់​ដើម​នេះ​ទេ"</string>
<string name="external_drop_widget_pick_title" msgid="3486317258037690630">"ជ្រើស​ធាតុ​ក្រាហ្វិក ដើម្បី​​​បង្កើត"</string>
@@ -57,8 +58,6 @@
<string name="delete_target_label" msgid="1822697352535677073">"លុប​ចេញ"</string>
<string name="delete_target_uninstall_label" msgid="5100785476250872595">"លុប"</string>
<string name="info_target_label" msgid="8053346143994679532">"ព័ត៌មាន​កម្មវិធី"</string>
- <string name="accessibility_search_button" msgid="1628520399424565142">"ស្វែងរក"</string>
- <string name="accessibility_voice_search_button" msgid="4637324840434406584">"ស្វែងរក​តាម​សំឡេង"</string>
<string name="accessibility_all_apps_button" msgid="2603132375383800483">"កម្មវិធី"</string>
<string name="accessibility_delete_button" msgid="6466114477993744621">"លុប​ចេញ"</string>
<string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"លុប​បច្ចុប្បន្នភាព"</string>
@@ -86,7 +85,7 @@
<string name="workspace_scroll_format" msgid="8458889198184077399">"អេក្រង់​ដើម %1$d នៃ %2$d"</string>
<string name="apps_customize_apps_scroll_format" msgid="370005296147130238">"ទំព័រ​កម្មវិធី %1$d នៃ %2$d"</string>
<string name="apps_customize_widgets_scroll_format" msgid="3106209519974971521">"ទំព័រ​ធាតុ​ក្រាហ្វិក ​%1$d នៃ %2$d"</string>
- <string name="first_run_cling_title" msgid="2459738000155917941">"សូម​ស្វាគមន៍​"</string>
+ <string name="first_run_cling_title" msgid="2459738000155917941">"សូម​ស្វាគមន៍"</string>
<string name="first_run_cling_description" msgid="6447072552696253358">"ធ្វើ​ដោយ​ខ្លួន​ឯង​នៅ​លើ​អេក្រង់​ដើម។"</string>
<string name="first_run_cling_custom_content_hint" msgid="6090628589029352439"></string>
<string name="first_run_cling_search_bar_hint" msgid="5909062802402452582"></string>
diff --git a/res/values-kn-rIN/strings.xml b/res/values-kn-rIN/strings.xml
index e84ece03c..7a070511d 100644
--- a/res/values-kn-rIN/strings.xml
+++ b/res/values-kn-rIN/strings.xml
@@ -24,12 +24,13 @@
<string name="uid_name" msgid="7820867637514617527">"Android Core ಅಪ್ಲಿಕೇಶನ್‌ಗಳು"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
<string name="activity_not_found" msgid="8071924732094499514">"ಅಪ್ಲಿಕೇಶನ್‌ ಅನ್ನು ಸ್ಥಾಪಿಸಲಾಗಿಲ್ಲ"</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"ಅಪ್ಲಿಕೇಶನ್ ಲಭ್ಯವಿಲ್ಲ"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"ಡೌನ್‌ಲೋಡ್ ಮಾಡಲಾದ ಅಪ್ಲಿಕೇಶನ್ ಅನ್ನು ಸುರಕ್ಷಿತ ಮೋಡ್‌ನಲ್ಲಿ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"ಸುರಕ್ಷಿತ ಮೋಡ್‌ನಲ್ಲಿ ವಿಜೆಟ್‌ಗಳನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
<string name="widgets_tab_label" msgid="2921133187116603919">"ವಿಜೆಟ್‌ಗಳು"</string>
<string name="widget_adder" msgid="3201040140710381657">"ವಿಜೆಟ್‌ಗಳು"</string>
<string name="toggle_weight_watcher" msgid="5645299835184636119">"ಸ್ಮರಣೆ ತೋರಿಸು"</string>
<string name="long_press_widget_to_add" msgid="7699152356777458215">"ವಿಜೆಟ್ ಅನ್ನು ಆರಿಸಿಕೊಳ್ಳಲು ಸ್ಪರ್ಶಿಸಿ &amp; ಹಿಡಿದುಕೊಳ್ಳಿ."</string>
- <string name="market" msgid="2619650989819296998">"ಶಾಪ್‌"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="external_drop_widget_error" msgid="3165821058322217155">"ಈ ಮುಖಪುಟದ ಪರದೆಯಲ್ಲಿ ಐಟಂ ಅನ್ನು ಬಿಡಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ."</string>
<string name="external_drop_widget_pick_title" msgid="3486317258037690630">"ರಚಿಸಲು ವಿಜೆಟ್‌ ಆಯ್ಕೆಮಾಡಿ"</string>
@@ -57,8 +58,6 @@
<string name="delete_target_label" msgid="1822697352535677073">"ತೆಗೆದುಹಾಕು"</string>
<string name="delete_target_uninstall_label" msgid="5100785476250872595">"ಅಸ್ಥಾಪಿಸು"</string>
<string name="info_target_label" msgid="8053346143994679532">"ಅಪ್ಲಿಕೇಶನ್ ಮಾಹಿತಿ"</string>
- <string name="accessibility_search_button" msgid="1628520399424565142">"ಹುಡುಕು"</string>
- <string name="accessibility_voice_search_button" msgid="4637324840434406584">"ಧ್ವನಿ ಹುಡುಕಾಟ"</string>
<string name="accessibility_all_apps_button" msgid="2603132375383800483">"ಅಪ್ಲಿಕೇಶನ್‌ಗಳು"</string>
<string name="accessibility_delete_button" msgid="6466114477993744621">"ತೆಗೆದುಹಾಕು"</string>
<string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"ನವೀಕರಣವನ್ನು ಅಸ್ಥಾಪಿಸು"</string>
@@ -77,6 +76,7 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"ಮುಖಪುಟದ ಸೆಟ್ಟಿಂಗ್‌ಗಳು ಮತ್ತು ಶಾರ್ಟ್‌ಕಟ್‌ಗಳನ್ನು ಬರೆಯಿರಿ"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"ಮುಖಪುಟದಲ್ಲಿ ಸೆಟ್ಟಿಂಗ್‌ಗಳು ಮತ್ತು ಶಾರ್ಟ್‌ಕಟ್‌ಗಳನ್ನು ಬದಲಾಯಿಸಲು ಅಪ್ಲಿಕೇಶನ್‌ಗೆ ಅನುಮತಿ ನೀಡುತ್ತದೆ."</string>
<string name="gadget_error_text" msgid="6081085226050792095">"ವಿಜೆಟ್ ಲೋಡ್‌ ಮಾಡುವಲ್ಲಿ ಸಮಸ್ಯೆ"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"ಸೆಟಪ್"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"ಇದೊಂದು ಅಪ್ಲಿಕೇಶನ್ ಆಗಿದೆ ಮತ್ತು ಅಸ್ಥಾಪಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ."</string>
<string name="dream_name" msgid="1530253749244328964">"ರಾಕೆಟ್ ಲಾಂಚರ್"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"ಹೆಸರಿಲ್ಲದ ಫೋಲ್ಡರ್"</string>
@@ -96,6 +96,9 @@
<string name="migration_cling_use_default" msgid="2626475813981258626">"ಹೊಸದಾಗಿ ಪ್ರಾರಂಭಿಸು"</string>
<string name="workspace_cling_title" msgid="5626202359865825661">"ನಿಮ್ಮ ಸ್ಥಳವನ್ನು ವ್ಯವಸ್ಥಿತಗೊಳಿಸಿ"</string>
<string name="workspace_cling_move_item" msgid="528201129978005352">"ವಾಲ್‌ಪೇಪರ್‌, ವಿಜೆಟ್‌ಗಳು ಮತ್ತು ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ನಿರ್ವಹಿಸಲು ಹಿನ್ನೆಲೆಯನ್ನು ಸ್ಪರ್ಶಿಸಿ &amp; ಹಿಡಿದುಕೊಳ್ಳಿ."</string>
+ <string name="workspace_cling_longpress_title" msgid="9173998993909018310">"ವಾಲ್‌ಪೇಪರ್‌ಗಳು, ವಿಜೆಟ್‌ಗಳು, &amp; ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
+ <string name="workspace_cling_longpress_description" msgid="4119994475505235248">"ಕಸ್ಟಮೈಸ್ ಮಾಡಲು ಹಿನ್ನೆಲೆಯನ್ನು ಸ್ಪರ್ಶಿಸಿ &amp; ಒತ್ತಿ ಹಿಡಿಯಿರಿ"</string>
+ <string name="workspace_cling_longpress_dismiss" msgid="368660286867640874">"ಅರ್ಥವಾಯಿತು"</string>
<string name="folder_cling_title" msgid="3894908818693254164">"ಇಲ್ಲೊಂದು ಫೋಲ್ಡರ್ ಇದೆ"</string>
<string name="folder_cling_create_folder" msgid="6158215559475836131">"ಈ ರೀತಿ ರಚಿಸಲು, ಸ್ಪರ್ಶಿಸಿ &amp; ಆಪ್‌ ಹಿಡಿದುಕೊಂಡು ಮತ್ತೊಂದರ ಮೇಲೆ ಸರಿಸಿ."</string>
<string name="cling_dismiss" msgid="8962359497601507581">"ಸರಿ"</string>
diff --git a/res/values-ko-land/strings.xml b/res/values-ko-land/strings.xml
deleted file mode 100644
index b976926f0..000000000
--- a/res/values-ko-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="delete_target_label" msgid="4155210680095864979"></string>
- <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
- <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index 41c854ec3..c73b431bd 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -24,12 +24,13 @@
<string name="uid_name" msgid="7820867637514617527">"Android 핵심 앱"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
<string name="activity_not_found" msgid="8071924732094499514">"앱이 설치되지 않았습니다."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"앱을 사용할 수 없음"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"다운로드한 앱은 안전 모드에서 사용할 수 없습니다."</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"안전 모드에서 위젯 사용 중지됨"</string>
<string name="widgets_tab_label" msgid="2921133187116603919">"위젯"</string>
<string name="widget_adder" msgid="3201040140710381657">"위젯"</string>
<string name="toggle_weight_watcher" msgid="5645299835184636119">"메모리 표시"</string>
<string name="long_press_widget_to_add" msgid="7699152356777458215">"위젯을 선택하려면 길게 터치하세요."</string>
- <string name="market" msgid="2619650989819296998">"쇼핑하기"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d×%2$d"</string>
<string name="external_drop_widget_error" msgid="3165821058322217155">"홈 화면에 항목을 놓을 수 없습니다."</string>
<string name="external_drop_widget_pick_title" msgid="3486317258037690630">"만들 위젯 선택"</string>
@@ -57,8 +58,6 @@
<string name="delete_target_label" msgid="1822697352535677073">"삭제"</string>
<string name="delete_target_uninstall_label" msgid="5100785476250872595">"제거"</string>
<string name="info_target_label" msgid="8053346143994679532">"앱 정보"</string>
- <string name="accessibility_search_button" msgid="1628520399424565142">"검색"</string>
- <string name="accessibility_voice_search_button" msgid="4637324840434406584">"음성 검색"</string>
<string name="accessibility_all_apps_button" msgid="2603132375383800483">"앱"</string>
<string name="accessibility_delete_button" msgid="6466114477993744621">"삭제"</string>
<string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"업데이트 제거"</string>
diff --git a/res/values-ky-rKG/strings.xml b/res/values-ky-rKG/strings.xml
index 5b50555ae..a8a605b26 100644
--- a/res/values-ky-rKG/strings.xml
+++ b/res/values-ky-rKG/strings.xml
@@ -24,13 +24,13 @@
<string name="uid_name" msgid="7820867637514617527">"Android Core колдонмолору"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
<string name="activity_not_found" msgid="8071924732094499514">"Колдонмо орнотулган эмес."</string>
- <!-- no translation found for safemode_shortcut_error (9160126848219158407) -->
- <skip />
+ <string name="activity_not_available" msgid="7456344436509528827">"Колдонмо жеткиликтүү эмес"</string>
+ <string name="safemode_shortcut_error" msgid="9160126848219158407">"Жүктөп алынган колдонмо Коопсуз режиминде иштен чыгарылды"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"Виджеттер Коопсуз режимде өчүрүлгөн"</string>
<string name="widgets_tab_label" msgid="2921133187116603919">"Виджеттер"</string>
<string name="widget_adder" msgid="3201040140710381657">"Виджеттер"</string>
<string name="toggle_weight_watcher" msgid="5645299835184636119">"Мемди көргөзүү"</string>
<string name="long_press_widget_to_add" msgid="7699152356777458215">"Виджетти тандаш үчүн, басып туруңуз"</string>
- <string name="market" msgid="2619650989819296998">"Дүкөн"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="external_drop_widget_error" msgid="3165821058322217155">"Муну бул Үй экранына ыргытуу мүмкүн эмес."</string>
<string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Түзүлүүчү виджетти тандаңыз"</string>
@@ -58,8 +58,6 @@
<string name="delete_target_label" msgid="1822697352535677073">"Алып салуу"</string>
<string name="delete_target_uninstall_label" msgid="5100785476250872595">"Чечип салуу"</string>
<string name="info_target_label" msgid="8053346143994679532">"Колдонмо тууралуу"</string>
- <string name="accessibility_search_button" msgid="1628520399424565142">"Издөө"</string>
- <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Үн менен издөө"</string>
<string name="accessibility_all_apps_button" msgid="2603132375383800483">"Колдонмолор"</string>
<string name="accessibility_delete_button" msgid="6466114477993744621">"Алып салуу"</string>
<string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Жаңыртууну чечип салуу"</string>
@@ -78,6 +76,7 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"Үйдүн тууралоолорун жана тез чакырмаларын жазуу"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Колдонмого Үйдүн тууралоолорун жана тез чакырмаларын өзгөртүүгө уруксат берет."</string>
<string name="gadget_error_text" msgid="6081085226050792095">"Виджетти жүктөөдө маселе бар"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Орнотуу"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Бул системдик колдонмо жана аны чечкенге болбойт."</string>
<string name="dream_name" msgid="1530253749244328964">"Rocket Launcher"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"Аты жок фолдер"</string>
@@ -97,6 +96,9 @@
<string name="migration_cling_use_default" msgid="2626475813981258626">"ТАЗАСЫН БАШТОО"</string>
<string name="workspace_cling_title" msgid="5626202359865825661">"Өз мейкиндигиңизди уюштуруңуз"</string>
<string name="workspace_cling_move_item" msgid="528201129978005352">"Тушкагаздарды, виджеттерди жана тууралоолорду башкаруу үчүн фонду басып туруңуз."</string>
+ <string name="workspace_cling_longpress_title" msgid="9173998993909018310">"Тушкагаздар, виджеттер &amp; жөндөөлөр"</string>
+ <string name="workspace_cling_longpress_description" msgid="4119994475505235248">"Өзгөчөлөштүрүү үчүн фонго тийип &amp; коё бербей туруңуз"</string>
+ <string name="workspace_cling_longpress_dismiss" msgid="368660286867640874">"ТҮШҮНДҮМ"</string>
<string name="folder_cling_title" msgid="3894908818693254164">"Мынакей фолдер"</string>
<string name="folder_cling_create_folder" msgid="6158215559475836131">"Башкасын түзүш үчүн колдонмону басып туруп, башканын жанына жылдырыңыз."</string>
<string name="cling_dismiss" msgid="8962359497601507581">"OK"</string>
diff --git a/res/values-land/strings.xml b/res/values-land/strings.xml
deleted file mode 100644
index ec4c7e706..000000000
--- a/res/values-land/strings.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
--->
-
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- Manifest configuration. -->
- <skip />
-</resources>
diff --git a/res/values-land/styles.xml b/res/values-land/styles.xml
index 87a744455..8a255c91b 100644
--- a/res/values-land/styles.xml
+++ b/res/values-land/styles.xml
@@ -18,31 +18,25 @@
-->
<resources>
-<!-- Search Bar -->
- <style name="SearchButton">
- </style>
+
+ <!-- Search Bar -->
+ <style name="SearchButton"></style>
+
<style name="DropTargetButtonContainer">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">wrap_content</item>
</style>
- <style name="DropTargetButton">
- <item name="android:layout_width">wrap_content</item>
+
+ <!-- This style applies to the drop target when it is shown in the sidebar -->
+ <style name="DropTargetButton" parent="DropTargetButton.Base">
<item name="android:layout_height">wrap_content</item>
- <item name="android:layout_gravity">center</item>
<item name="android:gravity">center</item>
+ <item name="android:drawablePadding">0dp</item>
<item name="android:paddingTop">@dimen/toolbar_button_vertical_padding</item>
<item name="android:paddingBottom">@dimen/toolbar_button_vertical_padding</item>
<item name="android:paddingLeft">@dimen/toolbar_button_horizontal_padding</item>
<item name="android:paddingRight">@dimen/toolbar_button_horizontal_padding</item>
<item name="android:shadowColor">#DD000000</item>
- <item name="android:shadowDx">0.0</item>
- <item name="android:shadowDy">1.0</item>
- <item name="android:shadowRadius">4.0</item>
- </style>
-
-<!-- AppsCustomize -->
- <style name="TabIndicator.AppsCustomize">
- <item name="android:maxWidth">200dp</item>
</style>
-</resources>
+</resources> \ No newline at end of file
diff --git a/res/values-lo-rLA/strings.xml b/res/values-lo-rLA/strings.xml
index 1d953ffde..65f01b7f0 100644
--- a/res/values-lo-rLA/strings.xml
+++ b/res/values-lo-rLA/strings.xml
@@ -24,19 +24,20 @@
<string name="uid_name" msgid="7820867637514617527">"ແອັບພລິເຄຊັນຫຼັກຂອງ Android"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
<string name="activity_not_found" msgid="8071924732094499514">"ແອັບຯບໍ່ໄດ້ຖືກຕິດຕັ້ງ."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"ແອັບຯ​ໃຊ້​ບໍ່​ໄດ້"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"ແອັບຯ​ທີ່​ດາວ​ໂຫລດ​ແລ້ວ​ຖືກ​ປິດ​ການ​ນຳ​ໃຊ້​ໃນ Safe mode"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"​ວິດ​ເຈັດ​ຖືກ​ປິດ​ໃນ Safe mode"</string>
<string name="widgets_tab_label" msgid="2921133187116603919">"ວິດເຈັດ"</string>
<string name="widget_adder" msgid="3201040140710381657">"ວິດເຈັດ"</string>
<string name="toggle_weight_watcher" msgid="5645299835184636119">"ສະແດງຄວາມຈຳ"</string>
<string name="long_press_widget_to_add" msgid="7699152356777458215">"ສຳພັດຄ້າງໄວ້ ເພື່ອຈັບວິດເຈັດ."</string>
- <string name="market" msgid="2619650989819296998">"ຮ້ານຄ້າ"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="external_drop_widget_error" msgid="3165821058322217155">"ບໍ່ສາມາດວາງລາຍການໃສ່ໜ້າຈໍຫຼັກນີ້ໄດ້"</string>
<string name="external_drop_widget_pick_title" msgid="3486317258037690630">"ເລືອກວິດເຈັດເພື່ອສ້າງມັນ"</string>
<string name="rename_folder_label" msgid="3727762225964550653">"ຊື່ໂຟນເດີ"</string>
<string name="rename_folder_title" msgid="3771389277707820891">"ປ່ຽນຊື່ໂຟນເດີ"</string>
<string name="rename_action" msgid="5559600076028658757">"ຕົກລົງ"</string>
- <string name="cancel_action" msgid="7009134900002915310">"ຍົກ​ເລີກ​"</string>
+ <string name="cancel_action" msgid="7009134900002915310">"ຍົກ​ເລີກ"</string>
<string name="menu_item_add_item" msgid="1264911265836810421">"ເພີ່ມໃສ່ໜ້າຈໍຫຼັກ"</string>
<string name="group_applications" msgid="3797214114206693605">"ແອັບຯ"</string>
<string name="group_shortcuts" msgid="6012256992764410535">"ທາງລັດ"</string>
@@ -57,8 +58,6 @@
<string name="delete_target_label" msgid="1822697352535677073">"ລຶບ"</string>
<string name="delete_target_uninstall_label" msgid="5100785476250872595">"ຖອນ​ການ​ຕິດ​ຕັ້ງ"</string>
<string name="info_target_label" msgid="8053346143994679532">"ຂໍ້ມູນແອັບຯ"</string>
- <string name="accessibility_search_button" msgid="1628520399424565142">"ຊອກຫາ"</string>
- <string name="accessibility_voice_search_button" msgid="4637324840434406584">"ຊອກຫາດ້ວຍສຽງ"</string>
<string name="accessibility_all_apps_button" msgid="2603132375383800483">"ແອັບຯ"</string>
<string name="accessibility_delete_button" msgid="6466114477993744621">"ລຶບ"</string>
<string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"ຖອນອັບເດດ"</string>
@@ -118,7 +117,7 @@
<string name="package_state_unknown" msgid="7592128424511031410">"​ບໍ່​ຮູ້​ຈັກ"</string>
<string name="package_state_error" msgid="7672093962724223588">"ບໍ່​ໄດ້​ກູ້​ຂໍ້ມູນ​ມາ​ເທື່ອ"</string>
<string name="abandoned_clean_all" msgid="5256770727689657618">"ລຶບ​ທັງ​ໝົດ"</string>
- <string name="abandoned_clean_this" msgid="7610119707847920412">"ລຶບ​"</string>
+ <string name="abandoned_clean_this" msgid="7610119707847920412">"ລຶບ"</string>
<string name="abandoned_search" msgid="891119232568284442">"ຊອກຫາ"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"ແອັບຯ​ນີ້​ຍັງ​ບໍ່​ໄດ້​ຕິດ​ຕັ້ງ​ເທື່ອ"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"​ແອັບຯ​ສຳ​ລັບ​ໄອ​ຄອນ​ນີ້​ຍັງ​ບໍ່ໄດ້​ຕິດ​ຕັ້ງ​ເທື່ອ. ທ່ານ​ສາ​ມາດ​ລຶບ​ມັນ​ອອກ ຫຼື​ຊອກ​ຫາ​ແອັບຯ ແລ້ວ​ຕິດ​ຕັ້ງ​ມັນ​ໄດ້​ດ້ວຍ​ຕົນ​ເອງ."</string>
diff --git a/res/values-lt-land/strings.xml b/res/values-lt-land/strings.xml
deleted file mode 100644
index b976926f0..000000000
--- a/res/values-lt-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="delete_target_label" msgid="4155210680095864979"></string>
- <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
- <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml
index f7db79291..897c2fd9f 100644
--- a/res/values-lt/strings.xml
+++ b/res/values-lt/strings.xml
@@ -24,12 +24,13 @@
<string name="uid_name" msgid="7820867637514617527">"Pagrindinės „Android“ programos"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
<string name="activity_not_found" msgid="8071924732094499514">"Programa neįdiegta."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"Programa nepasiekiama"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Atsisiųsta programa išjungta Saugos režimu"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"Valdikliai išjungti Saugiame režime"</string>
<string name="widgets_tab_label" msgid="2921133187116603919">"Valdikliai"</string>
<string name="widget_adder" msgid="3201040140710381657">"Valdikliai"</string>
<string name="toggle_weight_watcher" msgid="5645299835184636119">"Rodyti atmintinę"</string>
<string name="long_press_widget_to_add" msgid="7699152356777458215">"Palieskite ir laikykite, kad pasirinkt. valdiklį."</string>
- <string name="market" msgid="2619650989819296998">"Apsipirkti"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="external_drop_widget_error" msgid="3165821058322217155">"Nepavyko nuvilkti elemento į šį pagrindinį ekraną."</string>
<string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Pasirinkite norimą kurti valdiklį"</string>
@@ -57,8 +58,6 @@
<string name="delete_target_label" msgid="1822697352535677073">"Pašalinti"</string>
<string name="delete_target_uninstall_label" msgid="5100785476250872595">"Pašalinti"</string>
<string name="info_target_label" msgid="8053346143994679532">"Programos informacija"</string>
- <string name="accessibility_search_button" msgid="1628520399424565142">"Ieškoti"</string>
- <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Paieška balsu"</string>
<string name="accessibility_all_apps_button" msgid="2603132375383800483">"Programos"</string>
<string name="accessibility_delete_button" msgid="6466114477993744621">"Pašalinti"</string>
<string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Pašalinti naujinį"</string>
diff --git a/res/values-lv-land/strings.xml b/res/values-lv-land/strings.xml
deleted file mode 100644
index b976926f0..000000000
--- a/res/values-lv-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="delete_target_label" msgid="4155210680095864979"></string>
- <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
- <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml
index 75eb0548b..13a47606d 100644
--- a/res/values-lv/strings.xml
+++ b/res/values-lv/strings.xml
@@ -24,12 +24,13 @@
<string name="uid_name" msgid="7820867637514617527">"Android pamatlietotnes"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
<string name="activity_not_found" msgid="8071924732094499514">"Lietotne nav instalēta."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"Lietotne nav pieejama."</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Lejupielādētā lietotne ir atspējota drošajā režīmā."</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"Logrīki atspējoti drošajā režīmā"</string>
<string name="widgets_tab_label" msgid="2921133187116603919">"Logrīki"</string>
<string name="widget_adder" msgid="3201040140710381657">"Logrīki"</string>
<string name="toggle_weight_watcher" msgid="5645299835184636119">"Rādīt atmiņu"</string>
<string name="long_press_widget_to_add" msgid="7699152356777458215">"Lai izvēlētos logrīku, pieskarieties un turiet to."</string>
- <string name="market" msgid="2619650989819296998">"Iepirkties"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="external_drop_widget_error" msgid="3165821058322217155">"Nevarēja nomest vienumu šajā sākuma ekrānā."</string>
<string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Izveidojamā logrīka izvēle"</string>
@@ -57,8 +58,6 @@
<string name="delete_target_label" msgid="1822697352535677073">"Noņemt"</string>
<string name="delete_target_uninstall_label" msgid="5100785476250872595">"Atinstalēt"</string>
<string name="info_target_label" msgid="8053346143994679532">"Lietotnes informācija"</string>
- <string name="accessibility_search_button" msgid="1628520399424565142">"Meklēt"</string>
- <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Meklēšana ar balsi"</string>
<string name="accessibility_all_apps_button" msgid="2603132375383800483">"Lietotnes"</string>
<string name="accessibility_delete_button" msgid="6466114477993744621">"Noņemt"</string>
<string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Atinstalēt atjauninājumu"</string>
diff --git a/res/values-mk-rMK/strings.xml b/res/values-mk-rMK/strings.xml
index 0d775712f..dcc55d7b7 100644
--- a/res/values-mk-rMK/strings.xml
+++ b/res/values-mk-rMK/strings.xml
@@ -24,12 +24,13 @@
<string name="uid_name" msgid="7820867637514617527">"Основни апликации на Android"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
<string name="activity_not_found" msgid="8071924732094499514">"Апликацијата не е инсталирана."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"Апликацијата не е достапна"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Преземената апликација е оневозможена во безбеден режим"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"Додатоците се оневозможени во безбеден режим"</string>
<string name="widgets_tab_label" msgid="2921133187116603919">"Виџети"</string>
<string name="widget_adder" msgid="3201040140710381657">"Виџети"</string>
<string name="toggle_weight_watcher" msgid="5645299835184636119">"Прикажи „Мени“"</string>
<string name="long_press_widget_to_add" msgid="7699152356777458215">"Допри и задржи за да се избере виџетот."</string>
- <string name="market" msgid="2619650989819296998">"Продавница"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="external_drop_widget_error" msgid="3165821058322217155">"Не можеше да се спушти елемент на овој екран на почетната страница."</string>
<string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Избери виџет за да се создаде"</string>
@@ -57,8 +58,6 @@
<string name="delete_target_label" msgid="1822697352535677073">"Отстрани"</string>
<string name="delete_target_uninstall_label" msgid="5100785476250872595">"Деинсталирај"</string>
<string name="info_target_label" msgid="8053346143994679532">"Информации за апликацијата"</string>
- <string name="accessibility_search_button" msgid="1628520399424565142">"Пребарај"</string>
- <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Гласовно пребарување"</string>
<string name="accessibility_all_apps_button" msgid="2603132375383800483">"Апликации"</string>
<string name="accessibility_delete_button" msgid="6466114477993744621">"Отстрани"</string>
<string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Деинсталирај ажурирање"</string>
@@ -77,6 +76,7 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"напиши подесувања и кратенки на почетна страница"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Овозможува апликацијата да ги менува подесувањата и кратенките на почетната страница."</string>
<string name="gadget_error_text" msgid="6081085226050792095">"Проблем при вчитувањето на виџетот"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Поставување"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Ова е системска апликација и не може да се деинсталира."</string>
<string name="dream_name" msgid="1530253749244328964">"Rocket Launcher"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"Неименувана папка"</string>
@@ -91,11 +91,14 @@
<string name="first_run_cling_search_bar_hint" msgid="5909062802402452582"></string>
<string name="first_run_cling_create_screens_hint" msgid="6950729526680114157">"Создади повеќе екрани за апликации и папки"</string>
<string name="migration_cling_title" msgid="9181776667882933767">"Копирај икони за апликација"</string>
- <string name="migration_cling_description" msgid="2752413805582227644">"Увези икони и папки од старите екрани на почетната страница?"</string>
+ <string name="migration_cling_description" msgid="2752413805582227644">"Зачувај икони и папки од твоите стари почетни страни?"</string>
<string name="migration_cling_copy_apps" msgid="946331230090919440">"КОПИРАЈ ИКОНИ"</string>
<string name="migration_cling_use_default" msgid="2626475813981258626">"СТАРТУВАЈ ОД ПОЧЕТОК"</string>
<string name="workspace_cling_title" msgid="5626202359865825661">"Организирајте го вашиот простор"</string>
<string name="workspace_cling_move_item" msgid="528201129978005352">"Допри и задржи ја заднината за управување со тапети, виџети и подесувања."</string>
+ <string name="workspace_cling_longpress_title" msgid="9173998993909018310">"Тапети, додатоци и поставки"</string>
+ <string name="workspace_cling_longpress_description" msgid="4119994475505235248">"Допрете и задржете на заднината за да приспособите"</string>
+ <string name="workspace_cling_longpress_dismiss" msgid="368660286867640874">"СФАТИВ"</string>
<string name="folder_cling_title" msgid="3894908818693254164">"Еве папка"</string>
<string name="folder_cling_create_folder" msgid="6158215559475836131">"За да создадете ваква, допрете и држете ја апликацијата, а потоа поместете ја врз другата."</string>
<string name="cling_dismiss" msgid="8962359497601507581">"Во ред"</string>
diff --git a/res/values-ml-rIN/strings.xml b/res/values-ml-rIN/strings.xml
index 32329f1c5..cf5efaae2 100644
--- a/res/values-ml-rIN/strings.xml
+++ b/res/values-ml-rIN/strings.xml
@@ -24,12 +24,13 @@
<string name="uid_name" msgid="7820867637514617527">"Android Core അപ്ലിക്കേഷനുകൾ"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
<string name="activity_not_found" msgid="8071924732094499514">"അപ്ലിക്കേഷൻ ഇൻസ്‌റ്റാളുചെ‌യ്‌തിട്ടില്ല."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"അപ്ലിക്കേഷൻ ലഭ്യമല്ല"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"ഡൗൺലോഡുചെയ്‌ത അപ്ലിക്കേഷൻ സുരക്ഷാ മോഡിൽ പ്രവർത്തനരഹിതമാക്കി"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"സുരക്ഷിത മോഡിൽ വിജറ്റുകൾ പ്രവർത്തനരഹിതമാക്കി"</string>
<string name="widgets_tab_label" msgid="2921133187116603919">"വിജറ്റുകൾ"</string>
<string name="widget_adder" msgid="3201040140710381657">"വിജറ്റുകൾ"</string>
<string name="toggle_weight_watcher" msgid="5645299835184636119">"മെമ്മറി കാണിക്കുക"</string>
<string name="long_press_widget_to_add" msgid="7699152356777458215">"ഒരു വിജറ്റ് ചേർക്കുന്നതിന് അത് സ്‌പർശിച്ച് പിടിക്കുക."</string>
- <string name="market" msgid="2619650989819296998">"ഷോപ്പുചെയ്യുക"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="external_drop_widget_error" msgid="3165821058322217155">"ഹോം സ്‌ക്രീനിൽ ഇനം വലിച്ചിടാനായില്ല."</string>
<string name="external_drop_widget_pick_title" msgid="3486317258037690630">"സൃഷ്‌ടിക്കുന്നതിന് വിജറ്റ് തിരഞ്ഞെടുക്കുക"</string>
@@ -57,8 +58,6 @@
<string name="delete_target_label" msgid="1822697352535677073">"നീക്കംചെയ്യുക"</string>
<string name="delete_target_uninstall_label" msgid="5100785476250872595">"അണ്‍ഇസ്റ്റാളുചെയ്യുക"</string>
<string name="info_target_label" msgid="8053346143994679532">"അപ്ലിക്കേഷൻ വിവരം"</string>
- <string name="accessibility_search_button" msgid="1628520399424565142">"തിരയുക"</string>
- <string name="accessibility_voice_search_button" msgid="4637324840434406584">"വോയ്‌സ് തിരയൽ"</string>
<string name="accessibility_all_apps_button" msgid="2603132375383800483">"അപ്ലിക്കേഷനുകൾ"</string>
<string name="accessibility_delete_button" msgid="6466114477993744621">"നീക്കംചെയ്യുക"</string>
<string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"അപ്‌ഡേറ്റ് അൺഇൻസ്റ്റാളുചെയ്യുക"</string>
@@ -77,6 +76,7 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"ഹോം ക്രമീകരണങ്ങളും കുറുക്കുവഴികളും റൈറ്റുചെയ്യുക"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"ഹോമിലെ ക്രമീകരണങ്ങളും കുറുക്കുവഴികളും മാറ്റാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."</string>
<string name="gadget_error_text" msgid="6081085226050792095">"വിജറ്റ് ലോഡുചെയ്യുന്നതിൽ പ്രശ്നമുണ്ട്"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"സജ്ജീകരിക്കുക"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"ഇതൊരു സിസ്‌റ്റം അപ്ലിക്കേഷനായതിനാൽ അൺഇൻസ്‌റ്റാളുചെയ്യാനാവില്ല."</string>
<string name="dream_name" msgid="1530253749244328964">"റോക്കറ്റ് ലോഞ്ചർ"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"പേരുനൽകാത്ത ഫോൾഡർ"</string>
@@ -96,6 +96,9 @@
<string name="migration_cling_use_default" msgid="2626475813981258626">"പുതുതായി ആരംഭിക്കുക"</string>
<string name="workspace_cling_title" msgid="5626202359865825661">"നിങ്ങളുടെ ഇടം ഓർഗനൈസുചെയ്യുക"</string>
<string name="workspace_cling_move_item" msgid="528201129978005352">"വാൾപേപ്പർ, വിജറ്റുകൾ, ക്രമീകരണങ്ങൾ എന്നിവ നിയന്ത്രിക്കുന്നതിന് പശ്ചാത്തലം സ്‌പർശിച്ച് പിടിക്കുക."</string>
+ <string name="workspace_cling_longpress_title" msgid="9173998993909018310">"വാൾപേപ്പറുകൾ, വിജറ്റുകൾ, ക്രമീകരണങ്ങൾ എന്നിവ"</string>
+ <string name="workspace_cling_longpress_description" msgid="4119994475505235248">"ഇഷ്‌ടാനുസൃതമാക്കുന്നതിന് പശ്‌ചാത്തലം സ്‌പർശിച്ചുപിടിക്കുക"</string>
+ <string name="workspace_cling_longpress_dismiss" msgid="368660286867640874">"മനസ്സിലായി"</string>
<string name="folder_cling_title" msgid="3894908818693254164">"ഇവിടെയൊരു ഫോൾഡർ ഉണ്ട്"</string>
<string name="folder_cling_create_folder" msgid="6158215559475836131">"ഇതുപോലൊന്ന് സൃഷ്‌ടിക്കുന്നതിന്, ഒരു അപ്ലിക്കേഷൻ സ്‌പർശിച്ച് പിടിച്ചുകൊണ്ട് അത് മറ്റൊന്നിലേക്ക് നീക്കുക."</string>
<string name="cling_dismiss" msgid="8962359497601507581">"ശരി"</string>
diff --git a/res/values-mn-rMN/strings.xml b/res/values-mn-rMN/strings.xml
index 34fb79423..f258b4c8d 100644
--- a/res/values-mn-rMN/strings.xml
+++ b/res/values-mn-rMN/strings.xml
@@ -24,12 +24,13 @@
<string name="uid_name" msgid="7820867637514617527">"Андройд үндсэн апп"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
<string name="activity_not_found" msgid="8071924732094499514">"Апп суугаагүй байна."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"Апп-г ашиглах боломжгүй"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Татаж авсан апп-г Аюулгүй горим дотроос идэвхгүйжүүлсэн"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"Safe горимд виджетүүдийг идэвхгүйжүүлсэн"</string>
<string name="widgets_tab_label" msgid="2921133187116603919">"Виджет"</string>
<string name="widget_adder" msgid="3201040140710381657">"Виджет"</string>
<string name="toggle_weight_watcher" msgid="5645299835184636119">"Мем харуулах"</string>
<string name="long_press_widget_to_add" msgid="7699152356777458215">"Виджетийг авах бол хүрээд барина уу."</string>
- <string name="market" msgid="2619650989819296998">"Дэлгүүр"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="external_drop_widget_error" msgid="3165821058322217155">"Энэ Нүүр дэлгэцэнд буулгах боломжгүй."</string>
<string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Үүсгэх виджетээ сонгоно уу"</string>
@@ -57,8 +58,6 @@
<string name="delete_target_label" msgid="1822697352535677073">"Устгах"</string>
<string name="delete_target_uninstall_label" msgid="5100785476250872595">"Устгах"</string>
<string name="info_target_label" msgid="8053346143994679532">"Апп мэдээлэл"</string>
- <string name="accessibility_search_button" msgid="1628520399424565142">"Хайх"</string>
- <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Дуун хайлт"</string>
<string name="accessibility_all_apps_button" msgid="2603132375383800483">"Апп"</string>
<string name="accessibility_delete_button" msgid="6466114477993744621">"Устгах"</string>
<string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Шинэчлэлийг устгах"</string>
diff --git a/res/values-mr-rIN/strings.xml b/res/values-mr-rIN/strings.xml
index 2e51e7b26..098e83023 100644
--- a/res/values-mr-rIN/strings.xml
+++ b/res/values-mr-rIN/strings.xml
@@ -24,12 +24,13 @@
<string name="uid_name" msgid="7820867637514617527">"Android Core Apps"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
<string name="activity_not_found" msgid="8071924732094499514">"अॅप स्थापित केलेला नाही."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"अॅप उपलब्ध नाही"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"डाउनलोड केलेला अ‍ॅप सुरक्षित मोड मध्‍ये अक्षम केला"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"विजेट सुरक्षित मोडमध्ये अक्षम झाले"</string>
<string name="widgets_tab_label" msgid="2921133187116603919">"विजेट"</string>
<string name="widget_adder" msgid="3201040140710381657">"विजेट"</string>
<string name="toggle_weight_watcher" msgid="5645299835184636119">"Mem दर्शवा"</string>
<string name="long_press_widget_to_add" msgid="7699152356777458215">"विजेट निवडण्यासाठी स्पर्श करा आणि धरून ठेवा."</string>
- <string name="market" msgid="2619650989819296998">"खरेदी करा"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="external_drop_widget_error" msgid="3165821058322217155">"या मुख्य स्क्रीनवर आयटम ड्रॉप करू शकलो नाही."</string>
<string name="external_drop_widget_pick_title" msgid="3486317258037690630">"तयार करण्यासाठी विजेट निवडा"</string>
@@ -57,8 +58,6 @@
<string name="delete_target_label" msgid="1822697352535677073">"काढा"</string>
<string name="delete_target_uninstall_label" msgid="5100785476250872595">"विस्थापित करा"</string>
<string name="info_target_label" msgid="8053346143994679532">"अॅप माहिती"</string>
- <string name="accessibility_search_button" msgid="1628520399424565142">"शोधा"</string>
- <string name="accessibility_voice_search_button" msgid="4637324840434406584">"व्हॉइस शोध"</string>
<string name="accessibility_all_apps_button" msgid="2603132375383800483">"अॅप्स"</string>
<string name="accessibility_delete_button" msgid="6466114477993744621">"काढा"</string>
<string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"अद्यतन विस्थापित करा"</string>
@@ -77,6 +76,7 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"मुख्यपृष्ठ सेटिंग्ज आणि शॉर्टकट लिहा"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"मुख्यपृष्ठातील सेटिंग्ज आणि शॉर्टकट बदलण्यास अॅप ला अनुमती देते."</string>
<string name="gadget_error_text" msgid="6081085226050792095">"विजेट लोड करण्यात समस्या"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"सेटअप"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"हा सिस्टम अॅप आहे आणि विस्थापित केला जाऊ शकत नाही."</string>
<string name="dream_name" msgid="1530253749244328964">"रॉकेट लाँचर"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"अनामित फोल्डर"</string>
@@ -96,6 +96,9 @@
<string name="migration_cling_use_default" msgid="2626475813981258626">"नव्याने प्रारंभ करा"</string>
<string name="workspace_cling_title" msgid="5626202359865825661">"आपले स्थान व्यवस्थापित करा"</string>
<string name="workspace_cling_move_item" msgid="528201129978005352">"वॉलपेपर, विजेट आणि सेटिंग्ज व्यवस्थापित करण्यासाठी पार्श्वभूमीस स्पर्श करा आणि धरून ठेवा."</string>
+ <string name="workspace_cling_longpress_title" msgid="9173998993909018310">"वॉलपेपर, विजेट आणि सेटिंग्ज"</string>
+ <string name="workspace_cling_longpress_description" msgid="4119994475505235248">"सानुकूल करण्यासाठी पार्श्वभूमीस स्पर्श करा आणि धरुन ठेवा"</string>
+ <string name="workspace_cling_longpress_dismiss" msgid="368660286867640874">"समजले"</string>
<string name="folder_cling_title" msgid="3894908818693254164">"येथे एक फोल्डर आहे"</string>
<string name="folder_cling_create_folder" msgid="6158215559475836131">"यासारखे एखादे तयार करण्यासाठी अॅप ला स्पर्श करा आणि धरून ठेवा, नंतर तो दुसर्‍यावर हलवा."</string>
<string name="cling_dismiss" msgid="8962359497601507581">"ठीक"</string>
diff --git a/res/values-ms-land/strings.xml b/res/values-ms-land/strings.xml
deleted file mode 100644
index b976926f0..000000000
--- a/res/values-ms-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="delete_target_label" msgid="4155210680095864979"></string>
- <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
- <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-ms-rMY/strings.xml b/res/values-ms-rMY/strings.xml
index 3c5876268..532b6ad8b 100644
--- a/res/values-ms-rMY/strings.xml
+++ b/res/values-ms-rMY/strings.xml
@@ -24,12 +24,13 @@
<string name="uid_name" msgid="7820867637514617527">"Apl Teras Android"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
<string name="activity_not_found" msgid="8071924732094499514">"Apl tidak dipasang."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"Apl tidak tersedia"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Apl yang dimuat turun dilumpuhkan dalam mod Selamat"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"Widget dilumpuhkan dalam mod Selamat"</string>
<string name="widgets_tab_label" msgid="2921133187116603919">"Widget"</string>
<string name="widget_adder" msgid="3201040140710381657">"Widget"</string>
<string name="toggle_weight_watcher" msgid="5645299835184636119">"Papar Mem"</string>
<string name="long_press_widget_to_add" msgid="7699152356777458215">"Sentuh &amp; tahan untuk mengambil widget."</string>
- <string name="market" msgid="2619650989819296998">"Beli-belah"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="external_drop_widget_error" msgid="3165821058322217155">"Tidak dapat melepaskan item pada Skrin Utama."</string>
<string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Pilih widget yang hendak dibuat"</string>
@@ -57,8 +58,6 @@
<string name="delete_target_label" msgid="1822697352535677073">"Alih keluar"</string>
<string name="delete_target_uninstall_label" msgid="5100785476250872595">"Nyahpasang"</string>
<string name="info_target_label" msgid="8053346143994679532">"Maklumat apl"</string>
- <string name="accessibility_search_button" msgid="1628520399424565142">"Cari"</string>
- <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Carian Suara"</string>
<string name="accessibility_all_apps_button" msgid="2603132375383800483">"Apl"</string>
<string name="accessibility_delete_button" msgid="6466114477993744621">"Alih keluar"</string>
<string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Nyahpasang kemas kini"</string>
diff --git a/res/values-my-rMM/strings.xml b/res/values-my-rMM/strings.xml
index 8048b02a3..668803587 100644
--- a/res/values-my-rMM/strings.xml
+++ b/res/values-my-rMM/strings.xml
@@ -24,19 +24,20 @@
<string name="uid_name" msgid="7820867637514617527">"Androidပင်မ အပ်ပလီကေးရှင်းများ"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
<string name="activity_not_found" msgid="8071924732094499514">"အပ်ပလီကေးရှင်း မထည့်သွင်းထားပါ"</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"App လက်လှမ်း မမှီပါ"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"ဒေါင်းလုဒ် appကို လုံခြုံရေး မုဒ်ထဲမှာ ပိတ်ထား"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"လုံခြုံရေး မုဒ်ထဲမှာ ဝီဂျက်များကို ပိတ်ထား"</string>
<string name="widgets_tab_label" msgid="2921133187116603919">"ဝဒ်ဂျက်များ"</string>
<string name="widget_adder" msgid="3201040140710381657">"ဝဒ်ဂျက်များ"</string>
<string name="toggle_weight_watcher" msgid="5645299835184636119">"Mem ကိုပြရန်"</string>
<string name="long_press_widget_to_add" msgid="7699152356777458215">"ဝဒ်ဂျက်တစ်ခုကို ကောက်ယူရန် ဖိနှိပ်ထားပါ"</string>
- <string name="market" msgid="2619650989819296998">"စျေးဝယ်ရန်"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="external_drop_widget_error" msgid="3165821058322217155">"ပင်မမျက်နှာစာတွင် အရာများ ချ လို့ မရတော့ပါ"</string>
<string name="external_drop_widget_pick_title" msgid="3486317258037690630">"ဝဒ်ဂျက်တစ်ခုအား ပြုဖန်တီးရန် ရွေးပါ"</string>
<string name="rename_folder_label" msgid="3727762225964550653">"အကန့်အမည်"</string>
<string name="rename_folder_title" msgid="3771389277707820891">"အကန့်အမည်ပြောင်းရန်"</string>
<string name="rename_action" msgid="5559600076028658757">"ကောင်းပြီ"</string>
- <string name="cancel_action" msgid="7009134900002915310">"ပယ်ဖျက်သည်"</string>
+ <string name="cancel_action" msgid="7009134900002915310">"ထားတော့"</string>
<string name="menu_item_add_item" msgid="1264911265836810421">"ပင်မမျက်နှာစာသို့ ထည့်ပါ"</string>
<string name="group_applications" msgid="3797214114206693605">"အပ်ပလီကေးရှင်းများ"</string>
<string name="group_shortcuts" msgid="6012256992764410535">"အတိုကောက်မှတ်သားမှုများ"</string>
@@ -57,11 +58,9 @@
<string name="delete_target_label" msgid="1822697352535677073">"ဖယ်ရှာခြင်း"</string>
<string name="delete_target_uninstall_label" msgid="5100785476250872595">"ဖယ်ရှားခြင်း"</string>
<string name="info_target_label" msgid="8053346143994679532">"အပ်ပလီကေးရှင်း အချက်အလက်များ"</string>
- <string name="accessibility_search_button" msgid="1628520399424565142">"ရှာဖွေခြင်း"</string>
- <string name="accessibility_voice_search_button" msgid="4637324840434406584">"အသံဖြင့် ရှာဖွေခြင်း"</string>
<string name="accessibility_all_apps_button" msgid="2603132375383800483">"အပ်ပလီကေးရှင်းများ"</string>
<string name="accessibility_delete_button" msgid="6466114477993744621">"ဖယ်ရှာခြင်း"</string>
- <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"အဆင့်မြှင့်ခြင်းကို ဖယ်ရှားပါ"</string>
+ <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"အဆင့်မြှင့်ခြင်းကို ဖယ်ရှားပါ"</string>
<string name="cab_menu_delete_app" msgid="7435191475867183689">"အပ်ပလီကေးရှင်းကို ဖယ်ရှားပါ"</string>
<string name="cab_menu_app_info" msgid="8593722221450362342">"အပ်ပလီကေးရှင်း အသေးစိတ် အချက်အလက်"</string>
<string name="cab_app_selection_text" msgid="374688303047985416">"အပ်ပလီကေးရှင်းတစ်ခု ရွေးချယ်ထားပြီး"</string>
@@ -77,6 +76,7 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"ပင်မမျက်နှာစာ အပြင်အဆင် နှင့် အတိုကောက်မှတ်သားမှုများအား ရေးသားခြင်း"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"ပင်မမျက်နှာစာတွင် ရှိသော အပြင်အဆင် နှင့် အတိုကောက်မှတ်သားမှုများ ကို အပ်ပလီကေးရှင်းအား ပြောင်းခွင့်ပြုခြင်း"</string>
<string name="gadget_error_text" msgid="6081085226050792095">"ဝဒ်ဂျက် တင်ရာတွင် ပြသနာ ရှိပါသည်"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"စဖွင့်သတ်မှတ်ရန်"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"ဤအပ်ပလီကေးရှင်းမှာ စစ်စတန်ပိုင်းဆိုင်ရာ အပ်ပလီကေးရှင်းဖြစ်ပါသည်။ ထုတ်ပစ်၍ မရပါ"</string>
<string name="dream_name" msgid="1530253749244328964">"ဒုံပျံ ပစ်လွှတ်သောအရာ"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"အမည်မရှိအကန့်"</string>
@@ -85,8 +85,8 @@
<string name="workspace_scroll_format" msgid="8458889198184077399">"ပင်မစာမျက်နှာ %1$d မှ %2$d"</string>
<string name="apps_customize_apps_scroll_format" msgid="370005296147130238">"အပ်ပလီကေးရှင်းပြ စာမျက်နှာ %1$d မှ %2$d"</string>
<string name="apps_customize_widgets_scroll_format" msgid="3106209519974971521">"ဝဒ်ဂျက်ပြ စာမျက်နှာ %1$d မှ %2$d"</string>
- <string name="first_run_cling_title" msgid="2459738000155917941">"ကြိုဆိုပါသည်"</string>
- <string name="first_run_cling_description" msgid="6447072552696253358">"ကိုယ့်အိမ်ကိုယ့်ယာလို သဘောထားပါ"</string>
+ <string name="first_run_cling_title" msgid="2459738000155917941">"မင်္ဂလာပါ"</string>
+ <string name="first_run_cling_description" msgid="6447072552696253358">"ကိုယ့်အိမ်လို သဘောထားပါ"</string>
<string name="first_run_cling_custom_content_hint" msgid="6090628589029352439"></string>
<string name="first_run_cling_search_bar_hint" msgid="5909062802402452582"></string>
<string name="first_run_cling_create_screens_hint" msgid="6950729526680114157">"အပ်ပလီကေးရှင်း နှင့် အကန့်များအတွက် ဖန်သားပြင်မှာ ထပ်ထည့်ပါ"</string>
@@ -96,10 +96,13 @@
<string name="migration_cling_use_default" msgid="2626475813981258626">"START FRESH"</string>
<string name="workspace_cling_title" msgid="5626202359865825661">"စနစ်တကျဖြစ်အောင် ပြုလုပ်ပါ"</string>
<string name="workspace_cling_move_item" msgid="528201129978005352">"နောက်ခံကို ဖိကိုင်၍ နောက်ခံပုံ၊ဝဒ်ဂျက်များ၊အပြင်အဆင်များကို ထိန်းချုပ်ပါ"</string>
+ <string name="workspace_cling_longpress_title" msgid="9173998993909018310">"နောက်ခံများ၊ ဝီဂျက်များ&amp; ဆက်တင်များ"</string>
+ <string name="workspace_cling_longpress_description" msgid="4119994475505235248">"နောက်ခံကို စိတ်တိုင်းကျ ပြုလုပ်ရန် ထိလျက် &amp; ကိုင်ထားပါ"</string>
+ <string name="workspace_cling_longpress_dismiss" msgid="368660286867640874">"ရပြီ"</string>
<string name="folder_cling_title" msgid="3894908818693254164">"ဒီမှာ အကန့်တစ်ခုဖြစ်ပါသည်"</string>
<string name="folder_cling_create_folder" msgid="6158215559475836131">"ဤကဲ့သို့လုပ်ရန်အတွက်၊ အပ်ပလီကေးရှင်းတစ်ခုကို ဖိကိုင်ပြီး နောက်တစ်ခုပေါ်သို့ ရွှေ့လိုက်ပါ"</string>
<string name="cling_dismiss" msgid="8962359497601507581">"ကောင်းပြီ"</string>
- <string name="folder_opened" msgid="94695026776264709">"ဖွင့်ထားသောအကန့်, <xliff:g id="WIDTH">%1$d</xliff:g> နှင့် <xliff:g id="HEIGHT">%2$d</xliff:g>"</string>
+ <string name="folder_opened" msgid="94695026776264709">"ဖွင့်ထားသောအကန့်, <xliff:g id="WIDTH">%1$d</xliff:g> နှင့် <xliff:g id="HEIGHT">%2$d</xliff:g>"</string>
<string name="folder_tap_to_close" msgid="1884479294466410023">"အကန့်ကို ပိတ်ရန် ဖိကိုင်ပါ"</string>
<string name="folder_tap_to_rename" msgid="9191075570492871147">"အမည်ပြောင်းခြင်း အတည်ပြုရန် ဖိကိုင်ပါ"</string>
<string name="folder_closed" msgid="4100806530910930934">"ပိတ်ထားသောအကန့်"</string>
@@ -108,7 +111,7 @@
<string name="widget_button_text" msgid="2880537293434387943">"ဝဒ်ဂျက်များ"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"နောက်ခံများ"</string>
<string name="settings_button_text" msgid="8119458837558863227">"အပြင်အဆင်များ"</string>
- <string name="package_state_enqueued" msgid="6227252464303085641">"စောင့်နေ"</string>
+ <string name="package_state_enqueued" msgid="6227252464303085641">"စောင့်နေ"</string>
<string name="package_state_downloading" msgid="4088770468458724721">"ဒေါင်းလုဒ် လုပ်နေ"</string>
<string name="package_state_installing" msgid="7588193972189849870">"တပ်ဆင်နေ"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"မသိရ"</string>
diff --git a/res/values-nb-land/strings.xml b/res/values-nb-land/strings.xml
deleted file mode 100644
index b976926f0..000000000
--- a/res/values-nb-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="delete_target_label" msgid="4155210680095864979"></string>
- <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
- <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
index ff8280e73..a9bbe08ca 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -24,12 +24,13 @@
<string name="uid_name" msgid="7820867637514617527">"Kjerneapper for Android"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
<string name="activity_not_found" msgid="8071924732094499514">"Appen er ikke installert."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"Appen er ikke tilgjengelig"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"En nedlastet app er deaktivert i sikker modus"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"Moduler er deaktivert i sikker modus"</string>
<string name="widgets_tab_label" msgid="2921133187116603919">"Moduler"</string>
<string name="widget_adder" msgid="3201040140710381657">"Moduler"</string>
<string name="toggle_weight_watcher" msgid="5645299835184636119">"Vis minne"</string>
<string name="long_press_widget_to_add" msgid="7699152356777458215">"Trykk og hold inne for å plukke opp en modul."</string>
- <string name="market" msgid="2619650989819296998">"Butikk"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="external_drop_widget_error" msgid="3165821058322217155">"Kunne ikke slippe elementet på denne startsiden."</string>
<string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Velg modul for oppretting"</string>
@@ -57,8 +58,6 @@
<string name="delete_target_label" msgid="1822697352535677073">"Fjern"</string>
<string name="delete_target_uninstall_label" msgid="5100785476250872595">"Avinstaller"</string>
<string name="info_target_label" msgid="8053346143994679532">"App-info"</string>
- <string name="accessibility_search_button" msgid="1628520399424565142">"Søk"</string>
- <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Talesøk"</string>
<string name="accessibility_all_apps_button" msgid="2603132375383800483">"Apper"</string>
<string name="accessibility_delete_button" msgid="6466114477993744621">"Fjern"</string>
<string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Avinstaller oppdateringen"</string>
diff --git a/res/values-ne-rNP/strings.xml b/res/values-ne-rNP/strings.xml
index fe75ea70d..815873de9 100644
--- a/res/values-ne-rNP/strings.xml
+++ b/res/values-ne-rNP/strings.xml
@@ -24,13 +24,13 @@
<string name="uid_name" msgid="7820867637514617527">"Android मूल अनुप्रयोगहरू"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
<string name="activity_not_found" msgid="8071924732094499514">"अनुप्रयोग स्थापित छैन।"</string>
- <!-- no translation found for safemode_shortcut_error (9160126848219158407) -->
- <skip />
+ <string name="activity_not_available" msgid="7456344436509528827">"अनुप्रयोग उपलब्ध छैन"</string>
+ <string name="safemode_shortcut_error" msgid="9160126848219158407">"सुरक्षित मोडमा डाउनलोड गरेको अनुप्रयोग अक्षम गरिएको छ"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"सुरक्षित मोडमा विगेटहरू अक्षम गरियो"</string>
<string name="widgets_tab_label" msgid="2921133187116603919">"विजेटहरू"</string>
<string name="widget_adder" msgid="3201040140710381657">"विजेटहरू"</string>
<string name="toggle_weight_watcher" msgid="5645299835184636119">"Mem देखाउनुहोस्"</string>
<string name="long_press_widget_to_add" msgid="7699152356777458215">"एउटा विजेटलाई टिप्नको लागि टच गरेर होल्ड गर्नुहोस्।"</string>
- <string name="market" msgid="2619650989819296998">"पसल"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="external_drop_widget_error" msgid="3165821058322217155">"यो गृह स्क्रिनमा वस्तु खसाउन सकिँदैन।"</string>
<string name="external_drop_widget_pick_title" msgid="3486317258037690630">"सृजना गर्नको लागि विजेट छान्नुहोस्"</string>
@@ -58,8 +58,6 @@
<string name="delete_target_label" msgid="1822697352535677073">"हटाउनुहोस्"</string>
<string name="delete_target_uninstall_label" msgid="5100785476250872595">"हटाउनुहोस्"</string>
<string name="info_target_label" msgid="8053346143994679532">"अनुप्रयोग जानकारी"</string>
- <string name="accessibility_search_button" msgid="1628520399424565142">"खोज्नुहोस्"</string>
- <string name="accessibility_voice_search_button" msgid="4637324840434406584">"ध्वनि खोज"</string>
<string name="accessibility_all_apps_button" msgid="2603132375383800483">"अनुप्रयोगहरू"</string>
<string name="accessibility_delete_button" msgid="6466114477993744621">"हटाउनुहोस्"</string>
<string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"अद्यावधिक अस्थापित गर्नुहोस्"</string>
@@ -78,6 +76,7 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"गृह सेटिङहरू र सर्टकटहरू लेख्नुहोस्"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"गृहमा एउटा अनुप्रयोगलाई सेटिङ र सर्टकट बदल्न अनुमति दिनुहोस्।"</string>
<string name="gadget_error_text" msgid="6081085226050792095">"समस्या लोडिङ गर्ने विजेट"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"सेटअप"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"यो प्रणाली अनुप्रयोग हो र यसलाई स्थापना रद्द गर्न सकिँदैन।"</string>
<string name="dream_name" msgid="1530253749244328964">"रकेट लन्चर"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"बेनाम फोल्डर"</string>
@@ -99,6 +98,9 @@
<string name="migration_cling_use_default" msgid="2626475813981258626">"START FRESH"</string>
<string name="workspace_cling_title" msgid="5626202359865825661">"आफ्नो ठाउँ व्यवस्थापन गर्नुहोस्"</string>
<string name="workspace_cling_move_item" msgid="528201129978005352">"वालपेपर, विजेट र सेटिङ्स प्रबन्ध गर्न पृष्ठभूमिलाई टच गरेर होल्ड गर्नुहोस्।"</string>
+ <string name="workspace_cling_longpress_title" msgid="9173998993909018310">"वालपेपरहरू, विजेट; सेटिङहरू"</string>
+ <string name="workspace_cling_longpress_description" msgid="4119994475505235248">"छुनुहोस् ; अनुकूलन पृष्ठभूमि होल्ड गर्नुहोस्"</string>
+ <string name="workspace_cling_longpress_dismiss" msgid="368660286867640874">"बुझियो"</string>
<string name="folder_cling_title" msgid="3894908818693254164">"यहाँ एउटा फोल्डर छ"</string>
<string name="folder_cling_create_folder" msgid="6158215559475836131">"यस्तै एक किसिमका सिर्जना गर्न, अनुप्रयोगलाई टच गरेर होल्ड गर्नुहोस्, त्यसपछि यसलाई अर्को माथि सार्नुहोस्।"</string>
<string name="cling_dismiss" msgid="8962359497601507581">"ठिक छ"</string>
diff --git a/res/values-nl-land/strings.xml b/res/values-nl-land/strings.xml
deleted file mode 100644
index b976926f0..000000000
--- a/res/values-nl-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="delete_target_label" msgid="4155210680095864979"></string>
- <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
- <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index 470eb8722..8a32fd1d9 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -24,12 +24,13 @@
<string name="uid_name" msgid="7820867637514617527">"Android-kernapps"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
<string name="activity_not_found" msgid="8071924732094499514">"App is niet geïnstalleerd."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"App is niet beschikbaar"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Gedownloade app uitgeschakeld in veilige modus"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"Widgets uitgeschakeld in Veilige modus"</string>
<string name="widgets_tab_label" msgid="2921133187116603919">"Widgets"</string>
<string name="widget_adder" msgid="3201040140710381657">"Widgets"</string>
<string name="toggle_weight_watcher" msgid="5645299835184636119">"Geheugen weergeven"</string>
<string name="long_press_widget_to_add" msgid="7699152356777458215">"Blijf aanraken om een widget toe te voegen."</string>
- <string name="market" msgid="2619650989819296998">"Winkelen"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="external_drop_widget_error" msgid="3165821058322217155">"Kan item niet neerzetten in dit startscherm."</string>
<string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Widget selecteren om te maken"</string>
@@ -57,8 +58,6 @@
<string name="delete_target_label" msgid="1822697352535677073">"Verwijderen"</string>
<string name="delete_target_uninstall_label" msgid="5100785476250872595">"Verwijderen"</string>
<string name="info_target_label" msgid="8053346143994679532">"App-info"</string>
- <string name="accessibility_search_button" msgid="1628520399424565142">"Zoeken"</string>
- <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Gesproken zoekopdracht"</string>
<string name="accessibility_all_apps_button" msgid="2603132375383800483">"Apps"</string>
<string name="accessibility_delete_button" msgid="6466114477993744621">"Verwijderen"</string>
<string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Update verwijderen"</string>
diff --git a/res/values-pl-land/strings.xml b/res/values-pl-land/strings.xml
deleted file mode 100644
index b976926f0..000000000
--- a/res/values-pl-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="delete_target_label" msgid="4155210680095864979"></string>
- <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
- <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
index 61a51e0a5..4eabae96e 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -24,12 +24,13 @@
<string name="uid_name" msgid="7820867637514617527">"Główne aplikacje Androida"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
<string name="activity_not_found" msgid="8071924732094499514">"Aplikacja nie jest zainstalowana."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"Aplikacja niedostępna"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Pobrana aplikacja została wyłączona w trybie awaryjnym"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"Widżety są wyłączone w trybie bezpiecznym"</string>
<string name="widgets_tab_label" msgid="2921133187116603919">"Widżety"</string>
<string name="widget_adder" msgid="3201040140710381657">"Widżety"</string>
<string name="toggle_weight_watcher" msgid="5645299835184636119">"Pokaż pamięć"</string>
<string name="long_press_widget_to_add" msgid="7699152356777458215">"Aby dodać widżet, kliknij go i przytrzymaj."</string>
- <string name="market" msgid="2619650989819296998">"Sklep"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="external_drop_widget_error" msgid="3165821058322217155">"Nie można upuścić elementu na tym ekranie głównym."</string>
<string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Wybierz widżet, który chcesz dodać"</string>
@@ -57,8 +58,6 @@
<string name="delete_target_label" msgid="1822697352535677073">"Usuń"</string>
<string name="delete_target_uninstall_label" msgid="5100785476250872595">"Odinstaluj"</string>
<string name="info_target_label" msgid="8053346143994679532">"Informacje o aplikacji"</string>
- <string name="accessibility_search_button" msgid="1628520399424565142">"Szukaj"</string>
- <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Wyszukiwanie głosowe"</string>
<string name="accessibility_all_apps_button" msgid="2603132375383800483">"Aplikacje"</string>
<string name="accessibility_delete_button" msgid="6466114477993744621">"Usuń"</string>
<string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Odinstaluj aktualizację"</string>
diff --git a/res/values-port/styles.xml b/res/values-port/styles.xml
deleted file mode 100644
index ab6a1eb92..000000000
--- a/res/values-port/styles.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
--->
-
-<resources>
-<!-- AppsCustomize -->
- <style name="TabIndicator.AppsCustomize">
- <item name="android:maxWidth">130dp</item>
- </style>
-</resources>
diff --git a/res/values-pt-land/strings.xml b/res/values-pt-land/strings.xml
deleted file mode 100644
index b976926f0..000000000
--- a/res/values-pt-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="delete_target_label" msgid="4155210680095864979"></string>
- <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
- <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-pt-rPT-land/strings.xml b/res/values-pt-rPT-land/strings.xml
deleted file mode 100644
index b976926f0..000000000
--- a/res/values-pt-rPT-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="delete_target_label" msgid="4155210680095864979"></string>
- <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
- <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
index 2fe062a4a..4397ebf81 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -24,12 +24,13 @@
<string name="uid_name" msgid="7820867637514617527">"Aplicações principais do Android"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
<string name="activity_not_found" msgid="8071924732094499514">"A aplicação não está instalada."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"A aplicação não está disponível"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Aplicação transferida desativada no Modo de segurança"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"Widgets desativados no Modo de segurança"</string>
<string name="widgets_tab_label" msgid="2921133187116603919">"Widgets"</string>
<string name="widget_adder" msgid="3201040140710381657">"Widgets"</string>
<string name="toggle_weight_watcher" msgid="5645299835184636119">"Mostrar mem"</string>
<string name="long_press_widget_to_add" msgid="7699152356777458215">"Prima sem soltar para escolher um widget."</string>
- <string name="market" msgid="2619650989819296998">"Comprar"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="external_drop_widget_error" msgid="3165821058322217155">"Não foi possível largar o item neste Ecrã Principal."</string>
<string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Escolher um widget para criar"</string>
@@ -57,8 +58,6 @@
<string name="delete_target_label" msgid="1822697352535677073">"Remover"</string>
<string name="delete_target_uninstall_label" msgid="5100785476250872595">"Desinstalar"</string>
<string name="info_target_label" msgid="8053346143994679532">"Informações da aplicação"</string>
- <string name="accessibility_search_button" msgid="1628520399424565142">"Pesquisar"</string>
- <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Pesquisa por Voz"</string>
<string name="accessibility_all_apps_button" msgid="2603132375383800483">"Aplicações"</string>
<string name="accessibility_delete_button" msgid="6466114477993744621">"Remover"</string>
<string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Desinstalar atualização"</string>
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index 20b193aa3..07c82143e 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -21,15 +21,16 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="application_name" msgid="5181331383435256801">"Launcher3"</string>
<string name="home" msgid="7658288663002113681">"Início"</string>
- <string name="uid_name" msgid="7820867637514617527">"Principais aplicativos do Android"</string>
+ <string name="uid_name" msgid="7820867637514617527">"Principais apps do Android"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
- <string name="activity_not_found" msgid="8071924732094499514">"O aplicativo não está instalado."</string>
+ <string name="activity_not_found" msgid="8071924732094499514">"O app não está instalado."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"O app não está disponível"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"App transferido por download desativado no modo de segurança"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"Widgets desativados no modo de segurança"</string>
<string name="widgets_tab_label" msgid="2921133187116603919">"Widgets"</string>
<string name="widget_adder" msgid="3201040140710381657">"Widgets"</string>
<string name="toggle_weight_watcher" msgid="5645299835184636119">"Mostrar memória"</string>
<string name="long_press_widget_to_add" msgid="7699152356777458215">"Toque e pressione para selecionar um widget."</string>
- <string name="market" msgid="2619650989819296998">"Comprar"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="external_drop_widget_error" msgid="3165821058322217155">"Não foi possível soltar o item nesta tela inicial."</string>
<string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Selecione um widget para criar"</string>
@@ -38,7 +39,7 @@
<string name="rename_action" msgid="5559600076028658757">"Ok"</string>
<string name="cancel_action" msgid="7009134900002915310">"Cancelar"</string>
<string name="menu_item_add_item" msgid="1264911265836810421">"Adicionar à tela inicial"</string>
- <string name="group_applications" msgid="3797214114206693605">"Aplicativos"</string>
+ <string name="group_applications" msgid="3797214114206693605">"Apps"</string>
<string name="group_shortcuts" msgid="6012256992764410535">"Atalhos"</string>
<string name="group_widgets" msgid="1569030723286851002">"Widgets"</string>
<string name="completely_out_of_space" msgid="6106288382070760318">"Não há mais espaço nas telas iniciais."</string>
@@ -49,49 +50,47 @@
<string name="shortcut_uninstalled" msgid="8176767991305701821">"O atalho \"<xliff:g id="NAME">%s</xliff:g>\" foi removido."</string>
<string name="shortcut_duplicate" msgid="9167217446062498127">"O atalho \"<xliff:g id="NAME">%s</xliff:g>\" já existe."</string>
<string name="title_select_shortcut" msgid="6680642571148153868">"Selecione um atalho"</string>
- <string name="title_select_application" msgid="3280812711670683644">"Selecione um aplicativo"</string>
- <string name="all_apps_button_label" msgid="9110807029020582876">"Aplicativos"</string>
+ <string name="title_select_application" msgid="3280812711670683644">"Selecione um app"</string>
+ <string name="all_apps_button_label" msgid="9110807029020582876">"Apps"</string>
<string name="all_apps_home_button_label" msgid="252062713717058851">"Início"</string>
<string name="delete_zone_label_workspace" msgid="4009607676751398685">"Remover"</string>
<string name="delete_zone_label_all_apps" msgid="8083826390278958980">"Desinstalar"</string>
<string name="delete_target_label" msgid="1822697352535677073">"Remover"</string>
<string name="delete_target_uninstall_label" msgid="5100785476250872595">"Desinstalar"</string>
- <string name="info_target_label" msgid="8053346143994679532">"Informações do aplicativo"</string>
- <string name="accessibility_search_button" msgid="1628520399424565142">"Pesquisar"</string>
- <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Pesquisa por voz"</string>
- <string name="accessibility_all_apps_button" msgid="2603132375383800483">"Aplicativos"</string>
+ <string name="info_target_label" msgid="8053346143994679532">"Informações do app"</string>
+ <string name="accessibility_all_apps_button" msgid="2603132375383800483">"Apps"</string>
<string name="accessibility_delete_button" msgid="6466114477993744621">"Remover"</string>
<string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Desinstalar atualização"</string>
- <string name="cab_menu_delete_app" msgid="7435191475867183689">"Desinstalar aplicativo"</string>
- <string name="cab_menu_app_info" msgid="8593722221450362342">"Detalhes do aplicativo"</string>
- <string name="cab_app_selection_text" msgid="374688303047985416">"Um aplicativo selecionado"</string>
+ <string name="cab_menu_delete_app" msgid="7435191475867183689">"Desinstalar app"</string>
+ <string name="cab_menu_app_info" msgid="8593722221450362342">"Detalhes do app"</string>
+ <string name="cab_app_selection_text" msgid="374688303047985416">"Um app selecionado"</string>
<string name="cab_widget_selection_text" msgid="1833458597831541241">"Um widget selecionado"</string>
<string name="cab_folder_selection_text" msgid="7999992513806132118">"Uma pasta selecionada"</string>
<string name="cab_shortcut_selection_text" msgid="2103811025667946450">"Um atalho selecionado"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"instalar atalhos"</string>
- <string name="permdesc_install_shortcut" msgid="923466509822011139">"Permite que um aplicativo adicione atalhos sem intervenção do usuário."</string>
+ <string name="permdesc_install_shortcut" msgid="923466509822011139">"Permite que um app adicione atalhos sem intervenção do usuário."</string>
<string name="permlab_uninstall_shortcut" msgid="864595034498083837">"desinstalar atalhos"</string>
- <string name="permdesc_uninstall_shortcut" msgid="5134129545001836849">"Permite que o aplicativo remova atalhos sem a intervenção do usuário."</string>
+ <string name="permdesc_uninstall_shortcut" msgid="5134129545001836849">"Permite que o app remova atalhos sem a intervenção do usuário."</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"ler configurações e atalhos da tela inicial"</string>
- <string name="permdesc_read_settings" msgid="5833423719057558387">"Permite que o aplicativo leia as configurações e os atalhos na tela inicial."</string>
+ <string name="permdesc_read_settings" msgid="5833423719057558387">"Permite que o app leia as configurações e os atalhos na tela inicial."</string>
<string name="permlab_write_settings" msgid="3574213698004620587">"gravar configurações e atalhos da tela inicial"</string>
- <string name="permdesc_write_settings" msgid="5440712911516509985">"Permite que o aplicativo altere as configurações e os atalhos na tela inicial."</string>
+ <string name="permdesc_write_settings" msgid="5440712911516509985">"Permite que o app altere as configurações e os atalhos na tela inicial."</string>
<string name="gadget_error_text" msgid="6081085226050792095">"Problema ao carregar o widget"</string>
<string name="gadget_setup_text" msgid="8274003207686040488">"Configuração"</string>
- <string name="uninstall_system_app_text" msgid="4172046090762920660">"Este é um aplicativo do sistema e não pode ser desinstalado."</string>
+ <string name="uninstall_system_app_text" msgid="4172046090762920660">"Este é um app do sistema e não pode ser desinstalado."</string>
<string name="dream_name" msgid="1530253749244328964">"Rocket Launcher"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"Pasta sem nome"</string>
<string name="workspace_description_format" msgid="2950174241104043327">"Tela inicial %1$d"</string>
<string name="default_scroll_format" msgid="7475544710230993317">"Página %1$d de %2$d"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"Tela inicial %1$d de %2$d"</string>
- <string name="apps_customize_apps_scroll_format" msgid="370005296147130238">"Página de aplicativos, %1$d de %2$d"</string>
+ <string name="apps_customize_apps_scroll_format" msgid="370005296147130238">"Página de apps, %1$d de %2$d"</string>
<string name="apps_customize_widgets_scroll_format" msgid="3106209519974971521">"Página de widgets, %1$d de %2$d"</string>
<string name="first_run_cling_title" msgid="2459738000155917941">"Bem-vindo"</string>
<string name="first_run_cling_description" msgid="6447072552696253358">"Fique à vontade."</string>
<string name="first_run_cling_custom_content_hint" msgid="6090628589029352439"></string>
<string name="first_run_cling_search_bar_hint" msgid="5909062802402452582"></string>
- <string name="first_run_cling_create_screens_hint" msgid="6950729526680114157">"Crie mais telas para aplicativos e pastas"</string>
- <string name="migration_cling_title" msgid="9181776667882933767">"Copiar ícones de aplicativos"</string>
+ <string name="first_run_cling_create_screens_hint" msgid="6950729526680114157">"Crie mais telas para apps e pastas"</string>
+ <string name="migration_cling_title" msgid="9181776667882933767">"Copiar ícones de apps"</string>
<string name="migration_cling_description" msgid="2752413805582227644">"Importar ícones e pastas de suas telas iniciais antigas?"</string>
<string name="migration_cling_copy_apps" msgid="946331230090919440">"COPIAR ÍCONES"</string>
<string name="migration_cling_use_default" msgid="2626475813981258626">"COMEÇAR DO ZERO"</string>
@@ -101,7 +100,7 @@
<string name="workspace_cling_longpress_description" msgid="4119994475505235248">"Toque e mantenha pressionado o segundo plano para personalizar"</string>
<string name="workspace_cling_longpress_dismiss" msgid="368660286867640874">"ENTENDI"</string>
<string name="folder_cling_title" msgid="3894908818693254164">"Aqui está uma pasta"</string>
- <string name="folder_cling_create_folder" msgid="6158215559475836131">"Para criar uma pasta como esta, mantenha pressionado um aplicativo e mova-o para cima de outro."</string>
+ <string name="folder_cling_create_folder" msgid="6158215559475836131">"Para criar uma pasta como esta, mantenha pressionado um app e mova-o para cima de outro."</string>
<string name="cling_dismiss" msgid="8962359497601507581">"Ok"</string>
<string name="folder_opened" msgid="94695026776264709">"Pasta aberta, <xliff:g id="WIDTH">%1$d</xliff:g> por <xliff:g id="HEIGHT">%2$d</xliff:g>"</string>
<string name="folder_tap_to_close" msgid="1884479294466410023">"Toque para fechar a pasta"</string>
@@ -120,6 +119,6 @@
<string name="abandoned_clean_all" msgid="5256770727689657618">"Remover tudo"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Remover"</string>
<string name="abandoned_search" msgid="891119232568284442">"Pesquisar"</string>
- <string name="abandoned_promises_title" msgid="7096178467971716750">"Este aplicativo não está instalado"</string>
- <string name="abandoned_promise_explanation" msgid="3990027586878167529">"O aplicativo deste ícone não está instalado. Você pode remover o ícone, ou procurar o aplicativo e instalá-lo manualmente."</string>
+ <string name="abandoned_promises_title" msgid="7096178467971716750">"Este app não está instalado"</string>
+ <string name="abandoned_promise_explanation" msgid="3990027586878167529">"O app deste ícone não está instalado. Você pode remover o ícone, ou procurar o app e instalá-lo manualmente."</string>
</resources>
diff --git a/res/values-rm-land/strings.xml b/res/values-rm-land/strings.xml
deleted file mode 100644
index b976926f0..000000000
--- a/res/values-rm-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="delete_target_label" msgid="4155210680095864979"></string>
- <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
- <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-ro-land/strings.xml b/res/values-ro-land/strings.xml
deleted file mode 100644
index b976926f0..000000000
--- a/res/values-ro-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="delete_target_label" msgid="4155210680095864979"></string>
- <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
- <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml
index 04aebc8b9..54cb46c3f 100644
--- a/res/values-ro/strings.xml
+++ b/res/values-ro/strings.xml
@@ -24,12 +24,13 @@
<string name="uid_name" msgid="7820867637514617527">"Android Core Apps"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
<string name="activity_not_found" msgid="8071924732094499514">"Aplicația nu este instalată."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"Aplicația nu este disponibilă"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Aplicația descărcată este dezactivată în modul de siguranță"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"Widgeturile sunt dezactivate în modul de siguranță"</string>
<string name="widgets_tab_label" msgid="2921133187116603919">"Widgeturi"</string>
<string name="widget_adder" msgid="3201040140710381657">"Widgeturi"</string>
<string name="toggle_weight_watcher" msgid="5645299835184636119">"Afișați memoria"</string>
<string name="long_press_widget_to_add" msgid="7699152356777458215">"Atingeți lung un widget pentru a-l alege."</string>
- <string name="market" msgid="2619650989819296998">"Cumpărați"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="external_drop_widget_error" msgid="3165821058322217155">"Nu se poate plasa articolul pe ecranul de pornire."</string>
<string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Alegeți widgetul de creat"</string>
@@ -57,8 +58,6 @@
<string name="delete_target_label" msgid="1822697352535677073">"Eliminați"</string>
<string name="delete_target_uninstall_label" msgid="5100785476250872595">"Dezinstalați"</string>
<string name="info_target_label" msgid="8053346143994679532">"Informații despre aplicație"</string>
- <string name="accessibility_search_button" msgid="1628520399424565142">"Căutați"</string>
- <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Căutare vocală"</string>
<string name="accessibility_all_apps_button" msgid="2603132375383800483">"Aplicații"</string>
<string name="accessibility_delete_button" msgid="6466114477993744621">"Eliminați"</string>
<string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Dezinstalați actualizarea"</string>
diff --git a/res/values-ru-land/strings.xml b/res/values-ru-land/strings.xml
deleted file mode 100644
index b976926f0..000000000
--- a/res/values-ru-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="delete_target_label" msgid="4155210680095864979"></string>
- <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
- <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index b1d7713a0..70ef0f591 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -24,12 +24,13 @@
<string name="uid_name" msgid="7820867637514617527">"Основные приложения Android"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
<string name="activity_not_found" msgid="8071924732094499514">"Приложение удалено"</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"Приложение недоступно"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Скачанное приложение отключено в безопасном режиме"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"Виджеты отключены в безопасном режиме"</string>
<string name="widgets_tab_label" msgid="2921133187116603919">"Виджеты"</string>
<string name="widget_adder" msgid="3201040140710381657">"Виджеты"</string>
<string name="toggle_weight_watcher" msgid="5645299835184636119">"Сведения о памяти"</string>
<string name="long_press_widget_to_add" msgid="7699152356777458215">"Чтобы выбрать виджет, нажмите на значок и удерживайте его."</string>
- <string name="market" msgid="2619650989819296998">"Google Play"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d x %2$d"</string>
<string name="external_drop_widget_error" msgid="3165821058322217155">"Не удалось добавить элемент на главный экран"</string>
<string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Выберите виджет"</string>
@@ -57,8 +58,6 @@
<string name="delete_target_label" msgid="1822697352535677073">"Удалить"</string>
<string name="delete_target_uninstall_label" msgid="5100785476250872595">"Удалить"</string>
<string name="info_target_label" msgid="8053346143994679532">"О приложении"</string>
- <string name="accessibility_search_button" msgid="1628520399424565142">"Поиск"</string>
- <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Голосовой поиск"</string>
<string name="accessibility_all_apps_button" msgid="2603132375383800483">"Приложения"</string>
<string name="accessibility_delete_button" msgid="6466114477993744621">"Удалить"</string>
<string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Удалить обновление"</string>
diff --git a/res/values-si-rLK/strings.xml b/res/values-si-rLK/strings.xml
index d334da92b..ab3abb83b 100644
--- a/res/values-si-rLK/strings.xml
+++ b/res/values-si-rLK/strings.xml
@@ -24,13 +24,13 @@
<string name="uid_name" msgid="7820867637514617527">"Android මධ්‍ය යෙදුම්"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
<string name="activity_not_found" msgid="8071924732094499514">"යෙදුම ස්ථාපනය කර නැත."</string>
- <!-- no translation found for safemode_shortcut_error (9160126848219158407) -->
- <skip />
+ <string name="activity_not_available" msgid="7456344436509528827">"යෙදුම නොතිබේ"</string>
+ <string name="safemode_shortcut_error" msgid="9160126848219158407">"ආරක්ෂිත ආකාරය තුළ බාගන්න ලද යෙදුම් අබල කරන්න"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"සුරක්ෂිත ආකාරය තුළ විජටය අබල කරන ලදි"</string>
<string name="widgets_tab_label" msgid="2921133187116603919">"විජට්"</string>
<string name="widget_adder" msgid="3201040140710381657">"විජට්"</string>
<string name="toggle_weight_watcher" msgid="5645299835184636119">"Mem පෙන්වන්න"</string>
<string name="long_press_widget_to_add" msgid="7699152356777458215">"විජට් එක ස්පර්ශ කර අහුලා ගැනීමට අල්ලාගෙන සිටින්න."</string>
- <string name="market" msgid="2619650989819296998">"සාප්පුයාම"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="external_drop_widget_error" msgid="3165821058322217155">"මෙම මුල් පිටු තිරය වෙත අයිතමය ඇද හෙළිය නොහැකි විය."</string>
<string name="external_drop_widget_pick_title" msgid="3486317258037690630">"සැදීමට විජට් එක තෝරන්න"</string>
@@ -58,8 +58,6 @@
<string name="delete_target_label" msgid="1822697352535677073">"ඉවත් කරන්න"</string>
<string name="delete_target_uninstall_label" msgid="5100785476250872595">"අස්ථාපනය කරන්න"</string>
<string name="info_target_label" msgid="8053346143994679532">"යෙදුම් තොරතුරු"</string>
- <string name="accessibility_search_button" msgid="1628520399424565142">"සොයන්න"</string>
- <string name="accessibility_voice_search_button" msgid="4637324840434406584">"හඬ සෙවීම"</string>
<string name="accessibility_all_apps_button" msgid="2603132375383800483">"යෙදුම්"</string>
<string name="accessibility_delete_button" msgid="6466114477993744621">"ඉවත් කරන්න"</string>
<string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"යාවත්කාලිනය අස්ථාපනය කරන්න"</string>
@@ -78,6 +76,7 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"මුල් පිටු සැකසීම් සහ කෙටිමං ලියන්න"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"මුල් පිටුවේ සැකසීම් සහ කෙටිමං ඉවත් කිරීමට යෙදුමට අවසර දෙයි."</string>
<string name="gadget_error_text" msgid="6081085226050792095">"ගැටලු පූරණ විජට් එක"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"ස්ථාපනය කරන්න"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"මෙය පද්ධති යෙදුමක් වන අතර අස්ථාපනය කළ නොහැක."</string>
<string name="dream_name" msgid="1530253749244328964">"රොකට් ආරම්භකය"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"නම් නොකළ ෆෝල්ඩරය"</string>
@@ -97,6 +96,9 @@
<string name="migration_cling_use_default" msgid="2626475813981258626">"අලුතින් පටන්ගන්න"</string>
<string name="workspace_cling_title" msgid="5626202359865825661">"ඔබගේ ඉඩ සංවිධානය කරගන්න"</string>
<string name="workspace_cling_move_item" msgid="528201129978005352">"බිතුපත, විජට් සහ සැකසීම් කළමනාකරණය කිරීමට පසුබිම ස්පර්ශ කර අල්ලාගෙන සිටින්න."</string>
+ <string name="workspace_cling_longpress_title" msgid="9173998993909018310">"වෝල්පේපර, විජට්, සහ සැකසීම්"</string>
+ <string name="workspace_cling_longpress_description" msgid="4119994475505235248">"පසුබිම අභිරුචිකරණය කිරීමට ස්පර්ශ කර අල්ලා සිටින්න"</string>
+ <string name="workspace_cling_longpress_dismiss" msgid="368660286867640874">"තේරුණා"</string>
<string name="folder_cling_title" msgid="3894908818693254164">"මෙන්න ෆෝල්ඩරයක්"</string>
<string name="folder_cling_create_folder" msgid="6158215559475836131">"මෙවැනි එකක් තැනීමට, යෙදුමක් තට්ටු කර අල්ලාගෙන සිටින්න, අනතුරුව එය තවත් එකක් උඩින් ගෙන යන්න."</string>
<string name="cling_dismiss" msgid="8962359497601507581">"හරි"</string>
diff --git a/res/values-sk-land/strings.xml b/res/values-sk-land/strings.xml
deleted file mode 100644
index b976926f0..000000000
--- a/res/values-sk-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="delete_target_label" msgid="4155210680095864979"></string>
- <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
- <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml
index a00367949..3f41f2d7e 100644
--- a/res/values-sk/strings.xml
+++ b/res/values-sk/strings.xml
@@ -24,12 +24,13 @@
<string name="uid_name" msgid="7820867637514617527">"Android Core Apps"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
<string name="activity_not_found" msgid="8071924732094499514">"Aplikácia nie je nainštalovaná."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"Aplikácia nie je k dispozícii"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Stiahnutá aplikácia je v núdzovom režime zakázaná"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"Miniaplikácie sú v núdzovom režime zakázané"</string>
<string name="widgets_tab_label" msgid="2921133187116603919">"Miniaplikácie"</string>
<string name="widget_adder" msgid="3201040140710381657">"Miniaplikácie"</string>
<string name="toggle_weight_watcher" msgid="5645299835184636119">"Zobraziť pamäť"</string>
<string name="long_press_widget_to_add" msgid="7699152356777458215">"Miniaplikáciu pridáte stlačením a podržaním."</string>
- <string name="market" msgid="2619650989819296998">"Obchod"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="external_drop_widget_error" msgid="3165821058322217155">"Položku sa nepodarilo presunúť na túto plochu."</string>
<string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Zvoľte miniaplikáciu na vytvorenie"</string>
@@ -57,8 +58,6 @@
<string name="delete_target_label" msgid="1822697352535677073">"Odstrániť"</string>
<string name="delete_target_uninstall_label" msgid="5100785476250872595">"Odinštalovať"</string>
<string name="info_target_label" msgid="8053346143994679532">"Informácie o aplikácii"</string>
- <string name="accessibility_search_button" msgid="1628520399424565142">"Vyhľadať"</string>
- <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Hlasové vyhľadávanie"</string>
<string name="accessibility_all_apps_button" msgid="2603132375383800483">"Aplikácie"</string>
<string name="accessibility_delete_button" msgid="6466114477993744621">"Odstrániť"</string>
<string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Odinštalovať aktualizáciu"</string>
@@ -86,7 +85,7 @@
<string name="workspace_scroll_format" msgid="8458889198184077399">"Plocha %1$d z %2$d"</string>
<string name="apps_customize_apps_scroll_format" msgid="370005296147130238">"Stránka aplikácií %1$d z %2$d"</string>
<string name="apps_customize_widgets_scroll_format" msgid="3106209519974971521">"Stránka miniaplikácií %1$d z %2$d"</string>
- <string name="first_run_cling_title" msgid="2459738000155917941">"Vitajte"</string>
+ <string name="first_run_cling_title" msgid="2459738000155917941">"Vitajte!"</string>
<string name="first_run_cling_description" msgid="6447072552696253358">"Cíťte sa tu ako doma."</string>
<string name="first_run_cling_custom_content_hint" msgid="6090628589029352439"></string>
<string name="first_run_cling_search_bar_hint" msgid="5909062802402452582"></string>
@@ -94,7 +93,7 @@
<string name="migration_cling_title" msgid="9181776667882933767">"Kopírovanie ikon aplikácií"</string>
<string name="migration_cling_description" msgid="2752413805582227644">"Chcete importovať ikony a priečinky zo starých plôch?"</string>
<string name="migration_cling_copy_apps" msgid="946331230090919440">"SKOPÍROVAŤ IKONY"</string>
- <string name="migration_cling_use_default" msgid="2626475813981258626">"ZAČAŤ S PREDVOLENÝM ROZLOŽENÍM"</string>
+ <string name="migration_cling_use_default" msgid="2626475813981258626">"ZAČAŤ ODZNOVA"</string>
<string name="workspace_cling_title" msgid="5626202359865825661">"Usporiadajte svoj priestor"</string>
<string name="workspace_cling_move_item" msgid="528201129978005352">"Ak chcete spravovať tapetu, miniaplikácie a nastavenia, dotknite sa pozadia a podržte."</string>
<string name="workspace_cling_longpress_title" msgid="9173998993909018310">"Pozadia, miniaplikácie a nastavenia"</string>
diff --git a/res/values-sl-land/strings.xml b/res/values-sl-land/strings.xml
deleted file mode 100644
index b976926f0..000000000
--- a/res/values-sl-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="delete_target_label" msgid="4155210680095864979"></string>
- <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
- <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml
index 9c5bebd15..d5a34d58f 100644
--- a/res/values-sl/strings.xml
+++ b/res/values-sl/strings.xml
@@ -24,12 +24,13 @@
<string name="uid_name" msgid="7820867637514617527">"Osnovne aplikacije sistema Android"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
<string name="activity_not_found" msgid="8071924732094499514">"Aplikacija ni nameščena."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"Aplikacija ni na voljo"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Prenesena aplikacija je onemogočena v Varnem načinu"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"Pripomočki so onemogočeni v varnem načinu"</string>
<string name="widgets_tab_label" msgid="2921133187116603919">"Pripomočki"</string>
<string name="widget_adder" msgid="3201040140710381657">"Pripomočki"</string>
<string name="toggle_weight_watcher" msgid="5645299835184636119">"Pokaži pomnilnik"</string>
<string name="long_press_widget_to_add" msgid="7699152356777458215">"Za izbiro pripomočka se ga dotaknite in pridržite."</string>
- <string name="market" msgid="2619650989819296998">"Nakup"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="external_drop_widget_error" msgid="3165821058322217155">"Elementa ni mogoče spustiti na začetni zaslon."</string>
<string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Izberite pripomoček za ustvarjanje"</string>
@@ -57,8 +58,6 @@
<string name="delete_target_label" msgid="1822697352535677073">"Odstrani"</string>
<string name="delete_target_uninstall_label" msgid="5100785476250872595">"Odstrani"</string>
<string name="info_target_label" msgid="8053346143994679532">"Podatki o aplikaciji"</string>
- <string name="accessibility_search_button" msgid="1628520399424565142">"Iskanje"</string>
- <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Glasovno iskanje"</string>
<string name="accessibility_all_apps_button" msgid="2603132375383800483">"Aplikacije"</string>
<string name="accessibility_delete_button" msgid="6466114477993744621">"Odstrani"</string>
<string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Odstrani posodobitev"</string>
diff --git a/res/values-sr-land/strings.xml b/res/values-sr-land/strings.xml
deleted file mode 100644
index b976926f0..000000000
--- a/res/values-sr-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="delete_target_label" msgid="4155210680095864979"></string>
- <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
- <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml
index 421f8d3ac..9f40890c4 100644
--- a/res/values-sr/strings.xml
+++ b/res/values-sr/strings.xml
@@ -24,12 +24,13 @@
<string name="uid_name" msgid="7820867637514617527">"Основне Android апликације"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
<string name="activity_not_found" msgid="8071924732094499514">"Апликација није инсталирана."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"Апликација није доступна"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Преузета апликација је онемогућена у Безбедном режиму"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"Виџети су онемогућени у Безбедном режиму"</string>
<string name="widgets_tab_label" msgid="2921133187116603919">"Виџети"</string>
<string name="widget_adder" msgid="3201040140710381657">"Виџети"</string>
<string name="toggle_weight_watcher" msgid="5645299835184636119">"Прикажи меморију"</string>
<string name="long_press_widget_to_add" msgid="7699152356777458215">"Додирните и задржите да бисте изабрали виџет."</string>
- <string name="market" msgid="2619650989819296998">"Купујте"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d×%2$d"</string>
<string name="external_drop_widget_error" msgid="3165821058322217155">"Није могуће отпустити ставку на почетни екран."</string>
<string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Избор виџета за прављење"</string>
@@ -57,8 +58,6 @@
<string name="delete_target_label" msgid="1822697352535677073">"Уклони"</string>
<string name="delete_target_uninstall_label" msgid="5100785476250872595">"Деинсталирај"</string>
<string name="info_target_label" msgid="8053346143994679532">"Информације о апликацији"</string>
- <string name="accessibility_search_button" msgid="1628520399424565142">"Претражи"</string>
- <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Гласовна претрага"</string>
<string name="accessibility_all_apps_button" msgid="2603132375383800483">"Апликације"</string>
<string name="accessibility_delete_button" msgid="6466114477993744621">"Уклони"</string>
<string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Деинсталирај ажурирање"</string>
diff --git a/res/values-sv-land/strings.xml b/res/values-sv-land/strings.xml
deleted file mode 100644
index b976926f0..000000000
--- a/res/values-sv-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="delete_target_label" msgid="4155210680095864979"></string>
- <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
- <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
index e149c9efa..25f4d2623 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -24,12 +24,13 @@
<string name="uid_name" msgid="7820867637514617527">"Android Core Apps"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
<string name="activity_not_found" msgid="8071924732094499514">"Appen är inte installerad."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"Appen är inte tillgänglig"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Den hämtade appen inaktiverades i säkert läge"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"Widgets är inaktiverade i felsäkert läge"</string>
<string name="widgets_tab_label" msgid="2921133187116603919">"Widgetar"</string>
<string name="widget_adder" msgid="3201040140710381657">"Widgetar"</string>
<string name="toggle_weight_watcher" msgid="5645299835184636119">"Visa Mem"</string>
<string name="long_press_widget_to_add" msgid="7699152356777458215">"Tryck länge om du vill flytta en widget."</string>
- <string name="market" msgid="2619650989819296998">"Butik"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="external_drop_widget_error" msgid="3165821058322217155">"Objektet kunde inte släppas på startskärmen."</string>
<string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Ange vilken widget du vill använda"</string>
@@ -57,8 +58,6 @@
<string name="delete_target_label" msgid="1822697352535677073">"Ta bort"</string>
<string name="delete_target_uninstall_label" msgid="5100785476250872595">"Avinstallera"</string>
<string name="info_target_label" msgid="8053346143994679532">"Info om appen"</string>
- <string name="accessibility_search_button" msgid="1628520399424565142">"Sök"</string>
- <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Röstsökning"</string>
<string name="accessibility_all_apps_button" msgid="2603132375383800483">"Appar"</string>
<string name="accessibility_delete_button" msgid="6466114477993744621">"Ta bort"</string>
<string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Avinstallera uppdatering"</string>
diff --git a/res/values-sw-land/strings.xml b/res/values-sw-land/strings.xml
deleted file mode 100644
index b976926f0..000000000
--- a/res/values-sw-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="delete_target_label" msgid="4155210680095864979"></string>
- <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
- <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml
index 07d091393..fa810618b 100644
--- a/res/values-sw/strings.xml
+++ b/res/values-sw/strings.xml
@@ -24,12 +24,13 @@
<string name="uid_name" msgid="7820867637514617527">"Programu Msingi za Android"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
<string name="activity_not_found" msgid="8071924732094499514">"Programu haijasakinishwa."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"Programu haipatikani"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Programu iliyopakuliwa imezimwa katika Hali Salama"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"Wijeti zimezimwa katika hali ya Usalama"</string>
<string name="widgets_tab_label" msgid="2921133187116603919">"Wijeti"</string>
<string name="widget_adder" msgid="3201040140710381657">"Wijeti"</string>
<string name="toggle_weight_watcher" msgid="5645299835184636119">"Onyesha Kumbukumbu"</string>
<string name="long_press_widget_to_add" msgid="7699152356777458215">"Gusa na ushikilie ili kuteua wijeti."</string>
- <string name="market" msgid="2619650989819296998">"Nunua"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="external_drop_widget_error" msgid="3165821058322217155">"Haikuweza kudondosha kipengee kwenye skrini hii ya Kwanza."</string>
<string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Chagua wijeti ili uunde"</string>
@@ -57,8 +58,6 @@
<string name="delete_target_label" msgid="1822697352535677073">"Ondoa"</string>
<string name="delete_target_uninstall_label" msgid="5100785476250872595">"Ondoa"</string>
<string name="info_target_label" msgid="8053346143994679532">"Maelezo ya programu"</string>
- <string name="accessibility_search_button" msgid="1628520399424565142">"Tafuta"</string>
- <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Kutafuta kwa Kutamka"</string>
<string name="accessibility_all_apps_button" msgid="2603132375383800483">"Programu"</string>
<string name="accessibility_delete_button" msgid="6466114477993744621">"Ondoa"</string>
<string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Ondoa sasisho"</string>
diff --git a/res/values-sw340dp-port/styles.xml b/res/values-sw340dp-port/styles.xml
index 24f4ba2b1..8ac3b5ea1 100644
--- a/res/values-sw340dp-port/styles.xml
+++ b/res/values-sw340dp-port/styles.xml
@@ -24,9 +24,4 @@
<item name="android:paddingTop">@dimen/toolbar_button_vertical_padding</item>
<item name="android:paddingBottom">@dimen/toolbar_button_vertical_padding</item>
</style>
-
-<!-- AppsCustomize -->
- <style name="TabIndicator.AppsCustomize">
- <item name="android:maxWidth">150dp</item>
- </style>
</resources>
diff --git a/res/values-sw340dp/dimens.xml b/res/values-sw340dp/dimens.xml
index 69d6e58a3..c9f2981f7 100644
--- a/res/values-sw340dp/dimens.xml
+++ b/res/values-sw340dp/dimens.xml
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
+<!--
+ 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.
@@ -15,6 +16,9 @@
-->
<resources>
+
<!-- Drag padding to add to the bottom of drop targets -->
<dimen name="drop_target_drag_padding">20dp</dimen>
-</resources>
+ <dimen name="drop_target_text_size">16sp</dimen>
+
+</resources> \ No newline at end of file
diff --git a/res/values-sw720dp-port/styles.xml b/res/values-sw720dp-port/styles.xml
deleted file mode 100644
index 57f07acaf..000000000
--- a/res/values-sw720dp-port/styles.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
--->
-
-<resources>
- <style name="TabIndicator.AppsCustomize">
- <item name="android:maxWidth">180dp</item>
- </style>
-</resources>
diff --git a/res/values-sw720dp/styles.xml b/res/values-sw720dp/styles.xml
index 71f030400..cbc1e29b3 100644
--- a/res/values-sw720dp/styles.xml
+++ b/res/values-sw720dp/styles.xml
@@ -18,33 +18,22 @@
-->
<resources>
-<!-- Workspace -->
- <style name="TabIndicator.AppsCustomize">
- <item name="android:paddingLeft">32dp</item>
- <item name="android:paddingRight">32dp</item>
- <item name="android:textSize">14sp</item>
- <item name="android:maxWidth">240dp</item>
- </style>
- <style name="SearchButton">
- </style>
+ <!-- Workspace -->
+ <style name="SearchButton"></style>
+
<style name="DropTargetButtonContainer">
<item name="android:layout_width">0dp</item>
<item name="android:layout_height">match_parent</item>
</style>
- <style name="DropTargetButton">
- <item name="android:layout_width">wrap_content</item>
- <item name="android:layout_height">match_parent</item>
- <item name="android:layout_gravity">center</item>
- <item name="android:gravity">center_vertical</item>
- <item name="android:drawablePadding">7.5dp</item>
+
+ <style name="DropTargetButton" parent="DropTargetButton.Base">
<item name="android:paddingLeft">60dp</item>
<item name="android:paddingRight">60dp</item>
- <item name="android:textColor">#FFFFFFFF</item>
- <item name="android:textSize">16sp</item>
<item name="android:shadowColor">#393939</item>
<item name="android:shadowDx">0.0</item>
<item name="android:shadowDy">0.0</item>
<item name="android:shadowRadius">2.0</item>
</style>
-</resources>
+
+</resources> \ No newline at end of file
diff --git a/res/values-ta-rIN/strings.xml b/res/values-ta-rIN/strings.xml
index f3aef1cd7..9dba6f669 100644
--- a/res/values-ta-rIN/strings.xml
+++ b/res/values-ta-rIN/strings.xml
@@ -24,12 +24,13 @@
<string name="uid_name" msgid="7820867637514617527">"Android முக்கியப் பயன்பாடுகள்"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
<string name="activity_not_found" msgid="8071924732094499514">"பயன்பாடு நிறுவப்படவில்லை."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"பயன்பாடு இல்லை"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"இறக்கிய பயன்பாடு பாதுகாப்பு முறையில் முடக்கப்பட்டது"</string>
- <string name="widgets_tab_label" msgid="2921133187116603919">"விட்ஜெட்கள்"</string>
- <string name="widget_adder" msgid="3201040140710381657">"விட்ஜெட்கள்"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"பாதுகாப்புப் பயன்முறையில் விட்ஜெட்கள் முடக்கப்பட்டுள்ளன"</string>
+ <string name="widgets_tab_label" msgid="2921133187116603919">"ஷார்ட்கட்ஸ்"</string>
+ <string name="widget_adder" msgid="3201040140710381657">"ஷார்ட்கட்ஸ்"</string>
<string name="toggle_weight_watcher" msgid="5645299835184636119">"நினைவகத்தைக் காட்டு"</string>
- <string name="long_press_widget_to_add" msgid="7699152356777458215">"விட்ஜெட்டைத் தேர்வுசெய்ய தொட்டுப் &amp; பிடிக்கவும்."</string>
- <string name="market" msgid="2619650989819296998">"ஷாப்"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"விட்ஜெட்டைத் தேர்வுசெய்ய தொட்டுப் பிடிக்கவும்."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="external_drop_widget_error" msgid="3165821058322217155">"உருப்படியை இந்த முகப்புத் திரையில் விட முடியவில்லை."</string>
<string name="external_drop_widget_pick_title" msgid="3486317258037690630">"உருவாக்குவதற்கு விட்ஜெட்டைத் தேர்வுசெய்யவும்"</string>
@@ -40,7 +41,7 @@
<string name="menu_item_add_item" msgid="1264911265836810421">"முகப்புத் திரையில் சேர்"</string>
<string name="group_applications" msgid="3797214114206693605">"பயன்பாடுகள்"</string>
<string name="group_shortcuts" msgid="6012256992764410535">"குறுக்குவழிகள்"</string>
- <string name="group_widgets" msgid="1569030723286851002">"விட்ஜெட்கள்"</string>
+ <string name="group_widgets" msgid="1569030723286851002">"ஷார்ட்கட்ஸ்"</string>
<string name="completely_out_of_space" msgid="6106288382070760318">"உங்கள் முகப்புத் திரைகளில் வேறு இடம் இல்லை."</string>
<string name="out_of_space" msgid="4691004494942118364">"முகப்புத் திரையில் இடமில்லை."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"பிடித்தவை ட்ரேயில் இடமில்லை"</string>
@@ -57,8 +58,6 @@
<string name="delete_target_label" msgid="1822697352535677073">"அகற்று"</string>
<string name="delete_target_uninstall_label" msgid="5100785476250872595">"நிறுவல் நீக்கு"</string>
<string name="info_target_label" msgid="8053346143994679532">"பயன்பாட்டுத் தகவல்"</string>
- <string name="accessibility_search_button" msgid="1628520399424565142">"தேடு"</string>
- <string name="accessibility_voice_search_button" msgid="4637324840434406584">"குரல் தேடல்"</string>
<string name="accessibility_all_apps_button" msgid="2603132375383800483">"பயன்பாடுகள்"</string>
<string name="accessibility_delete_button" msgid="6466114477993744621">"அகற்று"</string>
<string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"புதுப்பிப்பை நிறுவல் நீக்கு"</string>
@@ -72,11 +71,12 @@
<string name="permdesc_install_shortcut" msgid="923466509822011139">"பயனரின் அனுமதி இல்லாமல் குறுக்குவழிகளைச் சேர்க்கப் பயன்பாட்டை அனுமதிக்கிறது."</string>
<string name="permlab_uninstall_shortcut" msgid="864595034498083837">"குறுக்குவழிகளை நிறுவல் நீக்குதல்"</string>
<string name="permdesc_uninstall_shortcut" msgid="5134129545001836849">"பயனரின் அனுமதி இல்லாமல் குறுக்குவழிகளை அகற்ற பயன்பாட்டை அனுமதிக்கிறது."</string>
- <string name="permlab_read_settings" msgid="1941457408239617576">"முகப்பின் அமைப்புகள் மற்றும் குறுக்குவழிகளைப் படித்தல்"</string>
- <string name="permdesc_read_settings" msgid="5833423719057558387">"முகப்பில் உள்ள அமைப்புகள் மற்றும் குறுக்குவழிகளைப் படிக்க பயன்பாட்டை அனுமதிக்கிறது."</string>
- <string name="permlab_write_settings" msgid="3574213698004620587">"முகப்பின் அமைப்புகள் மற்றும் குறுக்குவழிகளை எழுதுதல்"</string>
- <string name="permdesc_write_settings" msgid="5440712911516509985">"முகப்பில் உள்ள அமைப்புகள் மற்றும் குறுக்குவழிகளை மாற்ற பயன்பாட்டை அனுமதிக்கிறது."</string>
+ <string name="permlab_read_settings" msgid="1941457408239617576">"முகப்பின் அமைப்பு மற்றும் குறுக்குவழிகளைப் படித்தல்"</string>
+ <string name="permdesc_read_settings" msgid="5833423719057558387">"முகப்பில் உள்ள அமைப்பு மற்றும் குறுக்குவழிகளைப் படிக்க பயன்பாட்டை அனுமதிக்கிறது."</string>
+ <string name="permlab_write_settings" msgid="3574213698004620587">"முகப்பின் அமைப்பு மற்றும் குறுக்குவழிகளை எழுதுதல்"</string>
+ <string name="permdesc_write_settings" msgid="5440712911516509985">"முகப்பில் உள்ள அமைப்பு மற்றும் குறுக்குவழிகளை மாற்ற பயன்பாட்டை அனுமதிக்கிறது."</string>
<string name="gadget_error_text" msgid="6081085226050792095">"விட்ஜெட்டை ஏற்றுவதில் சிக்கல்"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"அமைவு"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"இது அமைப்பு பயன்பாடு என்பதால் நிறுவல் நீக்கம் செய்ய முடியாது."</string>
<string name="dream_name" msgid="1530253749244328964">"ராக்கெட் லாஞ்சர்"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"பெயரிடப்படாத கோப்புறை"</string>
@@ -95,9 +95,12 @@
<string name="migration_cling_copy_apps" msgid="946331230090919440">"ஐகான்களை நகலெடு"</string>
<string name="migration_cling_use_default" msgid="2626475813981258626">"புதிதாகத் தொடங்கு"</string>
<string name="workspace_cling_title" msgid="5626202359865825661">"இடத்தை ஒழுங்கமைக்கவும்"</string>
- <string name="workspace_cling_move_item" msgid="528201129978005352">"வால்பேப்பர், விட்ஜெட்கள் மற்றும் அமைப்புகளை நிர்வகிப்பதற்கு பின்புலத்தைத் தொட்டுப் &amp; பிடிக்கவும்."</string>
+ <string name="workspace_cling_move_item" msgid="528201129978005352">"வால்பேப்பர், விட்ஜெட்கள், அமைப்பை நிர்வகிக்க பின்புலத்தைத் தொட்டுப் பிடிக்கவும்."</string>
+ <string name="workspace_cling_longpress_title" msgid="9173998993909018310">"வால்பேப்பர்கள், விட்ஜெட்கள் &amp; அமைப்புகள்"</string>
+ <string name="workspace_cling_longpress_description" msgid="4119994475505235248">"தனிப்பயனாக்க, பின்னணியைத் தொட்டுப் பிடிக்கவும்"</string>
+ <string name="workspace_cling_longpress_dismiss" msgid="368660286867640874">"புரிந்தது"</string>
<string name="folder_cling_title" msgid="3894908818693254164">"இதோ கோப்புறை"</string>
- <string name="folder_cling_create_folder" msgid="6158215559475836131">"இதுபோன்ற ஒன்றை உருவாக்கப் பயன்பாட்டைத் தொட்டுப் &amp; பிடிக்கவும், பிறகு அதை வேறொன்றிற்கு நகர்த்தவும்."</string>
+ <string name="folder_cling_create_folder" msgid="6158215559475836131">"இதுபோன்ற ஒன்றை உருவாக்க பயன்பாட்டைத் தொட்டுப் பிடிக்கவும், பிறகு அதை வேறொன்றிற்கு நகர்த்தவும்."</string>
<string name="cling_dismiss" msgid="8962359497601507581">"சரி"</string>
<string name="folder_opened" msgid="94695026776264709">"திறக்கப்பட்டக் கோப்புறை, <xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g>"</string>
<string name="folder_tap_to_close" msgid="1884479294466410023">"கோப்புறையை மூட, தொடவும்"</string>
@@ -105,9 +108,9 @@
<string name="folder_closed" msgid="4100806530910930934">"கோப்புறை மூடப்பட்டது"</string>
<string name="folder_renamed" msgid="1794088362165669656">"கோப்புறை <xliff:g id="NAME">%1$s</xliff:g> என மறுபெயரிடப்பட்டது"</string>
<string name="folder_name_format" msgid="6629239338071103179">"கோப்புறை: <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"விட்ஜெட்கள்"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"ஷார்ட்கட்ஸ்"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"வால்பேப்பர்கள்"</string>
- <string name="settings_button_text" msgid="8119458837558863227">"அமைப்புகள்"</string>
+ <string name="settings_button_text" msgid="8119458837558863227">"அமைப்பு"</string>
<string name="package_state_enqueued" msgid="6227252464303085641">"காத்திருக்கிறது"</string>
<string name="package_state_downloading" msgid="4088770468458724721">"பதிவிறக்குகிறது"</string>
<string name="package_state_installing" msgid="7588193972189849870">"நிறுவுகிறது"</string>
diff --git a/res/values-te-rIN/strings.xml b/res/values-te-rIN/strings.xml
index b48d6b80d..bfbc7920f 100644
--- a/res/values-te-rIN/strings.xml
+++ b/res/values-te-rIN/strings.xml
@@ -24,12 +24,13 @@
<string name="uid_name" msgid="7820867637514617527">"Android ప్రధాన అనువర్తనాలు"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
<string name="activity_not_found" msgid="8071924732094499514">"అనువర్తనం ఇన్‌స్టాల్ చేయబడలేదు."</string>
- <string name="safemode_shortcut_error" msgid="9160126848219158407">"సురక్షిత మోడ్‌లో డౌన్‌లోడ్ చేసిన అనువర్తనం నిలిపివేయబడింది"</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"అనువర్తనం అందుబాటులో లేదు"</string>
+ <string name="safemode_shortcut_error" msgid="9160126848219158407">"డౌన్‌లోడ్ చేసిన అనువర్తనం సురక్షిత మోడ్‌లో నిలిపివేయబడింది"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"సురక్షిత మోడ్‌లో విడ్జెట్‌లు నిలిపివేయబడ్డాయి"</string>
<string name="widgets_tab_label" msgid="2921133187116603919">"విడ్జెట్‌లు"</string>
<string name="widget_adder" msgid="3201040140710381657">"విడ్జెట్‌లు"</string>
<string name="toggle_weight_watcher" msgid="5645299835184636119">"మెమరీ చూపు"</string>
<string name="long_press_widget_to_add" msgid="7699152356777458215">"విడ్జెట్‌ను ఎంచుకోవడానికి తాకి &amp; నొక్కి పెట్టండి."</string>
- <string name="market" msgid="2619650989819296998">"షాపింగ్ చేయి"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="external_drop_widget_error" msgid="3165821058322217155">"ఈ హోమ్ స్క్రీన్‌లో అంశాన్ని వదలడం సాధ్యపడలేదు."</string>
<string name="external_drop_widget_pick_title" msgid="3486317258037690630">"సృష్టించాల్సిన విడ్జెట్ ఎంచుకోండి"</string>
@@ -57,8 +58,6 @@
<string name="delete_target_label" msgid="1822697352535677073">"తీసివేయి"</string>
<string name="delete_target_uninstall_label" msgid="5100785476250872595">"అన్ఇన్‌స్టాల్ చేయి"</string>
<string name="info_target_label" msgid="8053346143994679532">"అనువర్తన సమాచారం"</string>
- <string name="accessibility_search_button" msgid="1628520399424565142">"శోధించు"</string>
- <string name="accessibility_voice_search_button" msgid="4637324840434406584">"వాయిస్ శోధన"</string>
<string name="accessibility_all_apps_button" msgid="2603132375383800483">"అనువర్తనాలు"</string>
<string name="accessibility_delete_button" msgid="6466114477993744621">"తీసివేయి"</string>
<string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"నవీకరణను అన్‌ఇన్‌స్టాల్ చేయి"</string>
@@ -77,6 +76,7 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"హోమ్ సెట్టింగ్‌లు మరియు సత్వరమార్గాలను వ్రాయడం"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"హోమ్‌లో సెట్టింగ్‌లు మరియు సత్వరమార్గాలను మార్చడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
<string name="gadget_error_text" msgid="6081085226050792095">"విడ్జెట్‌ను లోడ్ చేయడంలో సమస్య"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"సెటప్ చేయి"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"ఇది సిస్టమ్ అనువర్తనం మరియు దీన్ని అన్‌ఇన్‌స్టాల్ చేయడం సాధ్యపడదు."</string>
<string name="dream_name" msgid="1530253749244328964">"రాకెట్ లాంచర్"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"పేరు లేని ఫోల్డర్"</string>
@@ -96,6 +96,9 @@
<string name="migration_cling_use_default" msgid="2626475813981258626">"తాజాగా ప్రారంభించు"</string>
<string name="workspace_cling_title" msgid="5626202359865825661">"మీ స్థలాన్ని నిర్వహించండి"</string>
<string name="workspace_cling_move_item" msgid="528201129978005352">"వాల్‌., విడ్జె., సెట్టి. నిర్వ. నేపథ్యం తాకి &amp; నొక్కి పెట్టండి."</string>
+ <string name="workspace_cling_longpress_title" msgid="9173998993909018310">"వాల్‌పేపర్‌లు, విడ్జెట్‌లు &amp; సెట్టింగ్‌లు"</string>
+ <string name="workspace_cling_longpress_description" msgid="4119994475505235248">"అనుకూలీకరించడానికి నేపథ్యాన్ని నొక్కి &amp; ఉంచండి"</string>
+ <string name="workspace_cling_longpress_dismiss" msgid="368660286867640874">"అర్థమైంది"</string>
<string name="folder_cling_title" msgid="3894908818693254164">"ఇక్కడ ఫోల్డర్ ఉంది"</string>
<string name="folder_cling_create_folder" msgid="6158215559475836131">"ఇలాంటిది సృష్టించడానికి అనువర్తనాన్ని తాకి &amp; నొక్కి పెట్టండి, ఆపై మరోదాని పైన ఉంచండి."</string>
<string name="cling_dismiss" msgid="8962359497601507581">"సరే"</string>
diff --git a/res/values-th-land/strings.xml b/res/values-th-land/strings.xml
deleted file mode 100644
index b976926f0..000000000
--- a/res/values-th-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="delete_target_label" msgid="4155210680095864979"></string>
- <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
- <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml
index beed89844..0fc20d26f 100644
--- a/res/values-th/strings.xml
+++ b/res/values-th/strings.xml
@@ -24,12 +24,13 @@
<string name="uid_name" msgid="7820867637514617527">"แอปหลักของ Android"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
<string name="activity_not_found" msgid="8071924732094499514">"ไม่ได้ติดตั้งแอป"</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"แอปไม่พร้อมใช้งาน"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"แอปที่ดาวน์โหลดถูกปิดในโหมดปลอดภัย"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"มีการปิดใช้งานวิดเจ็ตในเซฟโหมด"</string>
<string name="widgets_tab_label" msgid="2921133187116603919">"วิดเจ็ต"</string>
<string name="widget_adder" msgid="3201040140710381657">"วิดเจ็ต"</string>
<string name="toggle_weight_watcher" msgid="5645299835184636119">"แสดง Mem"</string>
<string name="long_press_widget_to_add" msgid="7699152356777458215">"แตะค้างเพื่อรับวิดเจ็ต"</string>
- <string name="market" msgid="2619650989819296998">"เลือกซื้อ"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="external_drop_widget_error" msgid="3165821058322217155">"ไม่สามารถวางรายการลงในหน้าจอหลักนี้"</string>
<string name="external_drop_widget_pick_title" msgid="3486317258037690630">"เลือกวิดเจ็ตที่จะสร้าง"</string>
@@ -57,8 +58,6 @@
<string name="delete_target_label" msgid="1822697352535677073">"ลบ"</string>
<string name="delete_target_uninstall_label" msgid="5100785476250872595">"ถอนการติดตั้ง"</string>
<string name="info_target_label" msgid="8053346143994679532">"ข้อมูลแอป"</string>
- <string name="accessibility_search_button" msgid="1628520399424565142">"ค้นหา"</string>
- <string name="accessibility_voice_search_button" msgid="4637324840434406584">"ค้นหาด้วยเสียง"</string>
<string name="accessibility_all_apps_button" msgid="2603132375383800483">"แอป"</string>
<string name="accessibility_delete_button" msgid="6466114477993744621">"ลบ"</string>
<string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"ถอนการติดตั้งการอัปเดต"</string>
diff --git a/res/values-tl-land/strings.xml b/res/values-tl-land/strings.xml
deleted file mode 100644
index b976926f0..000000000
--- a/res/values-tl-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="delete_target_label" msgid="4155210680095864979"></string>
- <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
- <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml
index 7c6acd2ab..4d2f1d478 100644
--- a/res/values-tl/strings.xml
+++ b/res/values-tl/strings.xml
@@ -24,12 +24,13 @@
<string name="uid_name" msgid="7820867637514617527">"Android Core Apps"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
<string name="activity_not_found" msgid="8071924732094499514">"Hindi naka-install ang app."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"Hindi available ang app"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Naka-disable ang na-download na app sa Safe mode"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"Naka-disable ang mga widget sa Safe mode"</string>
<string name="widgets_tab_label" msgid="2921133187116603919">"Mga Widget"</string>
<string name="widget_adder" msgid="3201040140710381657">"Mga Widget"</string>
<string name="toggle_weight_watcher" msgid="5645299835184636119">"Ipakita ang Mem"</string>
<string name="long_press_widget_to_add" msgid="7699152356777458215">"Pindutin nang matagal upang kumuha ng widget."</string>
- <string name="market" msgid="2619650989819296998">"Mamili"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="external_drop_widget_error" msgid="3165821058322217155">"Hindi ma-drop ang item sa Home screen na ito."</string>
<string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Pumili ng widget na gagawin"</string>
@@ -57,8 +58,6 @@
<string name="delete_target_label" msgid="1822697352535677073">"Alisin"</string>
<string name="delete_target_uninstall_label" msgid="5100785476250872595">"I-uninstall"</string>
<string name="info_target_label" msgid="8053346143994679532">"Impormasyon ng app"</string>
- <string name="accessibility_search_button" msgid="1628520399424565142">"Hanapin"</string>
- <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Paghahanap Gamit ang Boses"</string>
<string name="accessibility_all_apps_button" msgid="2603132375383800483">"Apps"</string>
<string name="accessibility_delete_button" msgid="6466114477993744621">"Alisin"</string>
<string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"I-uninstall ang update"</string>
diff --git a/res/values-tr-land/strings.xml b/res/values-tr-land/strings.xml
deleted file mode 100644
index b976926f0..000000000
--- a/res/values-tr-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="delete_target_label" msgid="4155210680095864979"></string>
- <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
- <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml
index 6c0bb69a7..6c78f6f63 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/strings.xml
@@ -24,12 +24,13 @@
<string name="uid_name" msgid="7820867637514617527">"Android Çekirdek Uygulamaları"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
<string name="activity_not_found" msgid="8071924732094499514">"Uygulama yüklü değil."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"Uygulama kullanılamıyor"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"İndirilen uygulama Güvenli modda devre dışı bırakıldı"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"Güvenli modda widget\'lar devre dışı"</string>
<string name="widgets_tab_label" msgid="2921133187116603919">"Widget\'lar"</string>
<string name="widget_adder" msgid="3201040140710381657">"Widget\'lar"</string>
<string name="toggle_weight_watcher" msgid="5645299835184636119">"Belleği Göster"</string>
<string name="long_press_widget_to_add" msgid="7699152356777458215">"Widget seçmek için dokunun ve basılı tutun."</string>
- <string name="market" msgid="2619650989819296998">"Mağaza"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="external_drop_widget_error" msgid="3165821058322217155">"Öğe bu Ana ekrana bırakılamadı."</string>
<string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Oluşturmak için widget seçin"</string>
@@ -57,8 +58,6 @@
<string name="delete_target_label" msgid="1822697352535677073">"Kaldır"</string>
<string name="delete_target_uninstall_label" msgid="5100785476250872595">"Yüklemeyi kaldır"</string>
<string name="info_target_label" msgid="8053346143994679532">"Uygulama bilgileri"</string>
- <string name="accessibility_search_button" msgid="1628520399424565142">"Ara"</string>
- <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Sesli Arama"</string>
<string name="accessibility_all_apps_button" msgid="2603132375383800483">"Uygulamalar"</string>
<string name="accessibility_delete_button" msgid="6466114477993744621">"Kaldır"</string>
<string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Güncellemeyi kaldır"</string>
diff --git a/res/values-uk-land/strings.xml b/res/values-uk-land/strings.xml
deleted file mode 100644
index b976926f0..000000000
--- a/res/values-uk-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="delete_target_label" msgid="4155210680095864979"></string>
- <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
- <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml
index 52f3761ac..71e1816a3 100644
--- a/res/values-uk/strings.xml
+++ b/res/values-uk/strings.xml
@@ -23,13 +23,14 @@
<string name="home" msgid="7658288663002113681">"Головний екран"</string>
<string name="uid_name" msgid="7820867637514617527">"Базові програми Android"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
- <string name="activity_not_found" msgid="8071924732094499514">"Програму не встановлено."</string>
+ <string name="activity_not_found" msgid="8071924732094499514">"Додаток видалено."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"Додаток недоступний"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Завантажений додаток вимкнено в безпечному режимі"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"У безпечному режимі віджети вимкнено"</string>
<string name="widgets_tab_label" msgid="2921133187116603919">"Віджети"</string>
<string name="widget_adder" msgid="3201040140710381657">"Віджети"</string>
<string name="toggle_weight_watcher" msgid="5645299835184636119">"Показати пам’ять"</string>
<string name="long_press_widget_to_add" msgid="7699152356777458215">"Натисніть і утримуйте, щоб вибрати віджет."</string>
- <string name="market" msgid="2619650989819296998">"Магазин"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="external_drop_widget_error" msgid="3165821058322217155">"Не вдалося додати елемент на цей головний екран."</string>
<string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Вибрати віджет для створення"</string>
@@ -38,7 +39,7 @@
<string name="rename_action" msgid="5559600076028658757">"OК"</string>
<string name="cancel_action" msgid="7009134900002915310">"Скасувати"</string>
<string name="menu_item_add_item" msgid="1264911265836810421">"Додати на головний екран"</string>
- <string name="group_applications" msgid="3797214114206693605">"Програми"</string>
+ <string name="group_applications" msgid="3797214114206693605">"Додатки"</string>
<string name="group_shortcuts" msgid="6012256992764410535">"Ярлики"</string>
<string name="group_widgets" msgid="1569030723286851002">"Віджети"</string>
<string name="completely_out_of_space" msgid="6106288382070760318">"На головних екранах більше немає місця."</string>
@@ -50,16 +51,14 @@
<string name="shortcut_duplicate" msgid="9167217446062498127">"Ярлик \"<xliff:g id="NAME">%s</xliff:g>\" уже існує."</string>
<string name="title_select_shortcut" msgid="6680642571148153868">"Вибрати ярлик"</string>
<string name="title_select_application" msgid="3280812711670683644">"Вибрати програму"</string>
- <string name="all_apps_button_label" msgid="9110807029020582876">"Програми"</string>
+ <string name="all_apps_button_label" msgid="9110807029020582876">"Додатки"</string>
<string name="all_apps_home_button_label" msgid="252062713717058851">"Головний екран"</string>
<string name="delete_zone_label_workspace" msgid="4009607676751398685">"Вилучити"</string>
<string name="delete_zone_label_all_apps" msgid="8083826390278958980">"Видалити"</string>
<string name="delete_target_label" msgid="1822697352535677073">"Вилучити"</string>
<string name="delete_target_uninstall_label" msgid="5100785476250872595">"Видалити"</string>
<string name="info_target_label" msgid="8053346143994679532">"Про програму"</string>
- <string name="accessibility_search_button" msgid="1628520399424565142">"Пошук"</string>
- <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Голосовий пошук"</string>
- <string name="accessibility_all_apps_button" msgid="2603132375383800483">"Програми"</string>
+ <string name="accessibility_all_apps_button" msgid="2603132375383800483">"Додатки"</string>
<string name="accessibility_delete_button" msgid="6466114477993744621">"Вилучити"</string>
<string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Видалити оновлення"</string>
<string name="cab_menu_delete_app" msgid="7435191475867183689">"Видалити програму"</string>
diff --git a/res/values-ur-rPK/strings.xml b/res/values-ur-rPK/strings.xml
index 33b502e9b..ba1d3fa9a 100644
--- a/res/values-ur-rPK/strings.xml
+++ b/res/values-ur-rPK/strings.xml
@@ -24,13 +24,13 @@
<string name="uid_name" msgid="7820867637514617527">"‏Android کور ایپس"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
<string name="activity_not_found" msgid="8071924732094499514">"ایپ انسٹال نہیں ہے۔"</string>
- <!-- no translation found for safemode_shortcut_error (9160126848219158407) -->
- <skip />
+ <string name="activity_not_available" msgid="7456344436509528827">"ایپ دستیاب نہیں ہے"</string>
+ <string name="safemode_shortcut_error" msgid="9160126848219158407">"ڈاؤن لوڈ کردہ ایپ کو محفوظ وضع میں غیر فعال کر دیا گیا"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"ویجیٹس کو محفوظ وضع میں غیر فعال کر دیا گیا"</string>
<string name="widgets_tab_label" msgid="2921133187116603919">"ویجیٹس"</string>
<string name="widget_adder" msgid="3201040140710381657">"ویجیٹس"</string>
<string name="toggle_weight_watcher" msgid="5645299835184636119">"‏Mem دکھائیں"</string>
<string name="long_press_widget_to_add" msgid="7699152356777458215">"کوئی ویجیٹ منتخب کرنے کیلئے ٹچ کریں اور پکڑے رہیں۔"</string>
- <string name="market" msgid="2619650989819296998">"خریداری کریں"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="external_drop_widget_error" msgid="3165821058322217155">"آئٹم کو اس ہوم اسکرین پر ڈراپ نہیں کیا جا سکا۔"</string>
<string name="external_drop_widget_pick_title" msgid="3486317258037690630">"بنانے کیلئے ویجیٹ منتخب کریں"</string>
@@ -58,8 +58,6 @@
<string name="delete_target_label" msgid="1822697352535677073">"ہٹائیں"</string>
<string name="delete_target_uninstall_label" msgid="5100785476250872595">"اَن انسٹال کریں"</string>
<string name="info_target_label" msgid="8053346143994679532">"ایپ کی معلومات"</string>
- <string name="accessibility_search_button" msgid="1628520399424565142">"تلاش کریں"</string>
- <string name="accessibility_voice_search_button" msgid="4637324840434406584">"صوتی تلاش"</string>
<string name="accessibility_all_apps_button" msgid="2603132375383800483">"ایپس"</string>
<string name="accessibility_delete_button" msgid="6466114477993744621">"ہٹائیں"</string>
<string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"اپ ڈیٹ اَن انسٹال کریں"</string>
@@ -78,6 +76,7 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"ہوم ترتیبات اور شارٹ کٹس کو لکھیں"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"ایپ کو ہوم میں ترتیبات اور شارٹ کٹس کو تبدیل کرنے کی اجازت دیتا ہے۔"</string>
<string name="gadget_error_text" msgid="6081085226050792095">"ویجیٹ کو لوڈ کرنے میں مسئلہ"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"ترتیب دیں"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"یہ ایک سسٹم ایپ ہے اور اسے اَن انسٹال نہیں کیا جا سکتا ہے۔"</string>
<string name="dream_name" msgid="1530253749244328964">"راکٹ لانچر"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"بلا نام فولڈر"</string>
@@ -97,6 +96,9 @@
<string name="migration_cling_use_default" msgid="2626475813981258626">"نئے سرے سے شروع کریں"</string>
<string name="workspace_cling_title" msgid="5626202359865825661">"اپنی جگہ کو منظم کریں"</string>
<string name="workspace_cling_move_item" msgid="528201129978005352">"وال پیپر، ویجیٹس اور ترتیبات کا نظم کرنے کیلئے پس منظر کو ٹچ کریں اور پکڑ کر رکھیں۔"</string>
+ <string name="workspace_cling_longpress_title" msgid="9173998993909018310">"وال پیپرز، ویجیٹس اور ترتیبات"</string>
+ <string name="workspace_cling_longpress_description" msgid="4119994475505235248">"حسب ضرورت بنانے کیلئے پس منظر کو ٹچ کریں اور دبائے رکھیں"</string>
+ <string name="workspace_cling_longpress_dismiss" msgid="368660286867640874">"سمجھ آ گئی"</string>
<string name="folder_cling_title" msgid="3894908818693254164">"یہ ہے ایک فولڈر"</string>
<string name="folder_cling_create_folder" msgid="6158215559475836131">"اس طرح کا ایک بنانے کیلئے، کسی ایپ کو ٹچ کریں اور پکڑ کر رکھیں، پھر اسے کسی دوسرے میں منتقل کریں۔"</string>
<string name="cling_dismiss" msgid="8962359497601507581">"ٹھیک ہے"</string>
diff --git a/res/values-uz-rUZ/strings.xml b/res/values-uz-rUZ/strings.xml
index 791f6c888..a3c5670a3 100644
--- a/res/values-uz-rUZ/strings.xml
+++ b/res/values-uz-rUZ/strings.xml
@@ -24,13 +24,13 @@
<string name="uid_name" msgid="7820867637514617527">"Androidga asoslangan dasturlar"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
<string name="activity_not_found" msgid="8071924732094499514">"Ilova o‘rnatilmadi."</string>
- <!-- no translation found for safemode_shortcut_error (9160126848219158407) -->
- <skip />
+ <string name="activity_not_available" msgid="7456344436509528827">"Ilova mavjud emas"</string>
+ <string name="safemode_shortcut_error" msgid="9160126848219158407">"Yuklab olingan ilova xavfsiz rejimda o‘chirib qo‘yildi"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"Xavfsiz rejimda vidjetlar o‘chirib qo‘yilgan"</string>
<string name="widgets_tab_label" msgid="2921133187116603919">"Vidjetlar"</string>
<string name="widget_adder" msgid="3201040140710381657">"Vidjetlar"</string>
<string name="toggle_weight_watcher" msgid="5645299835184636119">"Xotirani ko‘rsatish"</string>
<string name="long_press_widget_to_add" msgid="7699152356777458215">"Vidjetni tanlash uchun bosib turing."</string>
- <string name="market" msgid="2619650989819296998">"Do‘kon"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="external_drop_widget_error" msgid="3165821058322217155">"Elementni ushbu \"Uy\" ekraniga tashlab bo‘lmadi."</string>
<string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Yaratish uchun vidjet tanlang"</string>
@@ -58,8 +58,6 @@
<string name="delete_target_label" msgid="1822697352535677073">"O‘chirish"</string>
<string name="delete_target_uninstall_label" msgid="5100785476250872595">"O‘chirish"</string>
<string name="info_target_label" msgid="8053346143994679532">"Ilova ma’lumoti"</string>
- <string name="accessibility_search_button" msgid="1628520399424565142">"Izlash"</string>
- <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Ovozli qidiruv"</string>
<string name="accessibility_all_apps_button" msgid="2603132375383800483">"Ilovalar"</string>
<string name="accessibility_delete_button" msgid="6466114477993744621">"O‘chirish"</string>
<string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Yangilashni o‘chirish"</string>
@@ -78,6 +76,7 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"Uy sozlamalari va yorliqlarini yozish"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Ilovaga \"Uy\" ekranidagi yorliqlar va sozlamalrni o‘zgartirish uchun ruxsat beradi."</string>
<string name="gadget_error_text" msgid="6081085226050792095">"Vidjetni yuklashda muammo"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Sozlash"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Bu tizim ilovasi, shuning uchun o‘chirib bo‘lmaydi."</string>
<string name="dream_name" msgid="1530253749244328964">"Rocket Launcher"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"Nomsiz jild"</string>
@@ -97,6 +96,9 @@
<string name="migration_cling_use_default" msgid="2626475813981258626">"YANGIDAN BOSHLASH"</string>
<string name="workspace_cling_title" msgid="5626202359865825661">"Joylaringizni boshqaring"</string>
<string name="workspace_cling_move_item" msgid="528201129978005352">"Fon rasmi, vidjet va sozlamalarni boshqarish uchun orqa fonga bosib turing"</string>
+ <string name="workspace_cling_longpress_title" msgid="9173998993909018310">"Orqa fon rasmlari, vidjet va sozlamalar"</string>
+ <string name="workspace_cling_longpress_description" msgid="4119994475505235248">"Orqa fonni moslashtirish uchun uni bosing va ushlab turing"</string>
+ <string name="workspace_cling_longpress_dismiss" msgid="368660286867640874">"OK"</string>
<string name="folder_cling_title" msgid="3894908818693254164">"Mana sizga jild"</string>
<string name="folder_cling_create_folder" msgid="6158215559475836131">"Bunga o‘xshaganini yaratish uchun bosib turing, keyin boshqasiga o‘ting."</string>
<string name="cling_dismiss" msgid="8962359497601507581">"OK"</string>
diff --git a/res/values-v17/styles.xml b/res/values-v17/styles.xml
index 71c4bfa66..11d2a1f82 100644
--- a/res/values-v17/styles.xml
+++ b/res/values-v17/styles.xml
@@ -3,7 +3,4 @@
<style name="PagedViewWidgetImageView">
<item name="android:paddingStart">@dimen/app_widget_preview_padding_left</item>
</style>
- <style name="SearchButton.WithPaddingStart">
- <item name="android:paddingStart">8dp</item>
- </style>
</resources>
diff --git a/res/values-vi-land/strings.xml b/res/values-vi-land/strings.xml
deleted file mode 100644
index b976926f0..000000000
--- a/res/values-vi-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="delete_target_label" msgid="4155210680095864979"></string>
- <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
- <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml
index 489123089..5bc16275e 100644
--- a/res/values-vi/strings.xml
+++ b/res/values-vi/strings.xml
@@ -24,12 +24,13 @@
<string name="uid_name" msgid="7820867637514617527">"Ứng dụng lõi Android"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
<string name="activity_not_found" msgid="8071924732094499514">"Ứng dụng chưa được cài đặt."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"Ứng dụng không có sẵn"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Ứng dụng đã tải xuống bị tắt ở chế độ An toàn"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"Tiện ích con bị vô hiệu hóa ở chế độ an toàn"</string>
<string name="widgets_tab_label" msgid="2921133187116603919">"Tiện ích con"</string>
<string name="widget_adder" msgid="3201040140710381657">"Tiện ích con"</string>
<string name="toggle_weight_watcher" msgid="5645299835184636119">"Hiển thị bộ nhớ"</string>
<string name="long_press_widget_to_add" msgid="7699152356777458215">"Chạm và giữ để chọn tiện ích con."</string>
- <string name="market" msgid="2619650989819296998">"Mua"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="external_drop_widget_error" msgid="3165821058322217155">"Không thể thả mục vào Màn hình chính này."</string>
<string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Chọn tiện ích con để tạo"</string>
@@ -57,8 +58,6 @@
<string name="delete_target_label" msgid="1822697352535677073">"Xóa"</string>
<string name="delete_target_uninstall_label" msgid="5100785476250872595">"Gỡ cài đặt"</string>
<string name="info_target_label" msgid="8053346143994679532">"Thông tin ứng dụng"</string>
- <string name="accessibility_search_button" msgid="1628520399424565142">"Tìm kiếm"</string>
- <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Tìm kiếm bằng giọng nói"</string>
<string name="accessibility_all_apps_button" msgid="2603132375383800483">"Ứng dụng"</string>
<string name="accessibility_delete_button" msgid="6466114477993744621">"Xóa"</string>
<string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Gỡ cài đặt cập nhật"</string>
diff --git a/res/values-zh-rCN-land/strings.xml b/res/values-zh-rCN-land/strings.xml
deleted file mode 100644
index b976926f0..000000000
--- a/res/values-zh-rCN-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="delete_target_label" msgid="4155210680095864979"></string>
- <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
- <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index 3365581be..b7c42fe5c 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -24,12 +24,13 @@
<string name="uid_name" msgid="7820867637514617527">"Android 核心应用"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
<string name="activity_not_found" msgid="8071924732094499514">"未安装该应用。"</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"应用不可用"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"安全模式下不允许使用下载的此应用"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"安全模式下不允许使用小部件"</string>
<string name="widgets_tab_label" msgid="2921133187116603919">"小部件"</string>
<string name="widget_adder" msgid="3201040140710381657">"小部件"</string>
<string name="toggle_weight_watcher" msgid="5645299835184636119">"显示内存空间"</string>
<string name="long_press_widget_to_add" msgid="7699152356777458215">"触摸并按住小部件即可选择。"</string>
- <string name="market" msgid="2619650989819296998">"商店"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="external_drop_widget_error" msgid="3165821058322217155">"无法将相关内容拖放到此主屏幕上。"</string>
<string name="external_drop_widget_pick_title" msgid="3486317258037690630">"选择要创建的小部件"</string>
@@ -57,8 +58,6 @@
<string name="delete_target_label" msgid="1822697352535677073">"删除"</string>
<string name="delete_target_uninstall_label" msgid="5100785476250872595">"卸载"</string>
<string name="info_target_label" msgid="8053346143994679532">"应用信息"</string>
- <string name="accessibility_search_button" msgid="1628520399424565142">"搜索"</string>
- <string name="accessibility_voice_search_button" msgid="4637324840434406584">"语音搜索"</string>
<string name="accessibility_all_apps_button" msgid="2603132375383800483">"应用"</string>
<string name="accessibility_delete_button" msgid="6466114477993744621">"删除"</string>
<string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"卸载更新内容"</string>
diff --git a/res/values-zh-rHK/strings.xml b/res/values-zh-rHK/strings.xml
index e1c206339..2eb700890 100644
--- a/res/values-zh-rHK/strings.xml
+++ b/res/values-zh-rHK/strings.xml
@@ -24,12 +24,13 @@
<string name="uid_name" msgid="7820867637514617527">"Android 核心應用程式"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
<string name="activity_not_found" msgid="8071924732094499514">"尚未安裝應用程式。"</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"目前無法使用這個應用程式"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"在安全模式中無法使用「已下載的應用程式」功能"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"在安全模式中無法使用小工具"</string>
<string name="widgets_tab_label" msgid="2921133187116603919">"小工具"</string>
<string name="widget_adder" msgid="3201040140710381657">"小工具"</string>
<string name="toggle_weight_watcher" msgid="5645299835184636119">"顯示記憶體"</string>
<string name="long_press_widget_to_add" msgid="7699152356777458215">"輕觸並按住小工具即可選取。"</string>
- <string name="market" msgid="2619650989819296998">"商店"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="external_drop_widget_error" msgid="3165821058322217155">"無法將項目拖放至主畫面。"</string>
<string name="external_drop_widget_pick_title" msgid="3486317258037690630">"選擇要建立的小工具"</string>
@@ -57,8 +58,6 @@
<string name="delete_target_label" msgid="1822697352535677073">"移除"</string>
<string name="delete_target_uninstall_label" msgid="5100785476250872595">"解除安裝"</string>
<string name="info_target_label" msgid="8053346143994679532">"應用程式資料"</string>
- <string name="accessibility_search_button" msgid="1628520399424565142">"搜尋"</string>
- <string name="accessibility_voice_search_button" msgid="4637324840434406584">"語音搜尋"</string>
<string name="accessibility_all_apps_button" msgid="2603132375383800483">"應用程式"</string>
<string name="accessibility_delete_button" msgid="6466114477993744621">"移除"</string>
<string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"解除安裝更新"</string>
@@ -69,9 +68,9 @@
<string name="cab_folder_selection_text" msgid="7999992513806132118">"已選取 1 個資料夾"</string>
<string name="cab_shortcut_selection_text" msgid="2103811025667946450">"已選取 1 個捷徑"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"安裝捷徑"</string>
- <string name="permdesc_install_shortcut" msgid="923466509822011139">"允許應用程式無需用戶許可也可新增捷徑。"</string>
+ <string name="permdesc_install_shortcut" msgid="923466509822011139">"允許應用程式無需使用者許可也可新增捷徑。"</string>
<string name="permlab_uninstall_shortcut" msgid="864595034498083837">"解除安裝捷徑"</string>
- <string name="permdesc_uninstall_shortcut" msgid="5134129545001836849">"允許應用程式無需用戶許可也可移除捷徑。"</string>
+ <string name="permdesc_uninstall_shortcut" msgid="5134129545001836849">"允許應用程式無需使用者許可也可移除捷徑。"</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"讀取主畫面的設定和捷徑"</string>
<string name="permdesc_read_settings" msgid="5833423719057558387">"允許應用程式讀取主畫面中的設定和捷徑。"</string>
<string name="permlab_write_settings" msgid="3574213698004620587">"寫入主畫面的設定和捷徑"</string>
diff --git a/res/values-zh-rTW-land/strings.xml b/res/values-zh-rTW-land/strings.xml
deleted file mode 100644
index b976926f0..000000000
--- a/res/values-zh-rTW-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="delete_target_label" msgid="4155210680095864979"></string>
- <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
- <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index 2d400596f..52e758396 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -24,12 +24,13 @@
<string name="uid_name" msgid="7820867637514617527">"Android 核心應用程式"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
<string name="activity_not_found" msgid="8071924732094499514">"應用程式未安裝。"</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"應用程式目前無法使用"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"在安全模式中無法使用「已下載的應用程式」功能"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"在安全模式下無法使用小工具"</string>
<string name="widgets_tab_label" msgid="2921133187116603919">"小工具"</string>
<string name="widget_adder" msgid="3201040140710381657">"小工具"</string>
<string name="toggle_weight_watcher" msgid="5645299835184636119">"顯示記憶體"</string>
<string name="long_press_widget_to_add" msgid="7699152356777458215">"輕觸並按住小工具即可選取。"</string>
- <string name="market" msgid="2619650989819296998">"購物"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="external_drop_widget_error" msgid="3165821058322217155">"無法將項目拖放至這個主螢幕上。"</string>
<string name="external_drop_widget_pick_title" msgid="3486317258037690630">"選擇要建立的小工具"</string>
@@ -57,8 +58,6 @@
<string name="delete_target_label" msgid="1822697352535677073">"移除"</string>
<string name="delete_target_uninstall_label" msgid="5100785476250872595">"解除安裝"</string>
<string name="info_target_label" msgid="8053346143994679532">"應用程式資訊"</string>
- <string name="accessibility_search_button" msgid="1628520399424565142">"搜尋"</string>
- <string name="accessibility_voice_search_button" msgid="4637324840434406584">"語音搜尋"</string>
<string name="accessibility_all_apps_button" msgid="2603132375383800483">"應用程式"</string>
<string name="accessibility_delete_button" msgid="6466114477993744621">"移除"</string>
<string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"解除安裝更新"</string>
diff --git a/res/values-zu-land/strings.xml b/res/values-zu-land/strings.xml
deleted file mode 100644
index b976926f0..000000000
--- a/res/values-zu-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="delete_target_label" msgid="4155210680095864979"></string>
- <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
- <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-zu/strings.xml b/res/values-zu/strings.xml
index 89cd5cc12..aea09e845 100644
--- a/res/values-zu/strings.xml
+++ b/res/values-zu/strings.xml
@@ -24,12 +24,13 @@
<string name="uid_name" msgid="7820867637514617527">"Izinhlelo zokusebenza ze-Android Core"</string>
<string name="folder_name" msgid="7371454440695724752"></string>
<string name="activity_not_found" msgid="8071924732094499514">"Uhlelo lokusebenza alufakiwe."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"Uhlelo lokusebenza alutholakali"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Uhlelo lokusebenza olulandiwe lukhutshaziwe kumodi ephephile"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"Amawijethi akhutshaziwe kwimodi yokuphepha"</string>
<string name="widgets_tab_label" msgid="2921133187116603919">"Amawijethi"</string>
<string name="widget_adder" msgid="3201040140710381657">"Amawijethi"</string>
<string name="toggle_weight_watcher" msgid="5645299835184636119">"Bonisa i-Mem"</string>
<string name="long_press_widget_to_add" msgid="7699152356777458215">"Thinta uphinde ubambe ukuze uphakamise iwijethi."</string>
- <string name="market" msgid="2619650989819296998">"Thenga"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="external_drop_widget_error" msgid="3165821058322217155">"Ayikwazanga ukwehlisela into kulesi sikrini se-Ikhaya."</string>
<string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Khetha iwijethi ongayidala"</string>
@@ -57,8 +58,6 @@
<string name="delete_target_label" msgid="1822697352535677073">"Susa"</string>
<string name="delete_target_uninstall_label" msgid="5100785476250872595">"Khipha"</string>
<string name="info_target_label" msgid="8053346143994679532">"Ulwazi lohlelo lokusebenza"</string>
- <string name="accessibility_search_button" msgid="1628520399424565142">"Sesha"</string>
- <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Ukusesha ngezwi"</string>
<string name="accessibility_all_apps_button" msgid="2603132375383800483">"Izinhlelo zokusebenza"</string>
<string name="accessibility_delete_button" msgid="6466114477993744621">"Susa"</string>
<string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Khipha isibuyekezo"</string>
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index 65f8f22a6..3331cdec4 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -18,13 +18,6 @@
<resources>
- <!-- DrawableStateProxyView specific attributes. These attributes are used to customize
- a DrawableStateProxyView view in XML files. -->
- <declare-styleable name="DrawableStateProxyView">
- <!-- The source view to delegate touch presses events to. -->
- <attr name="sourceViewId" format="integer" />
- </declare-styleable>
-
<!-- Page Indicator specific attributes. -->
<declare-styleable name="PageIndicator">
<attr name="windowSize" format="integer" />
@@ -76,13 +69,6 @@
<attr name="strokeWidth" format="float" />
</declare-styleable>
- <!-- HolographicLinearLayout specific attributes. -->
- <declare-styleable name="HolographicLinearLayout">
- <!-- The source view to generate and apply the drawable states to/from -->
- <attr name="sourceImageViewId" format="integer" />
- <attr name="stateHotwordOn" format="boolean" />
- </declare-styleable>
-
<!-- PagedView specific attributes. These attributes are used to customize
a PagedView view in XML files. -->
<declare-styleable name="PagedView">
@@ -130,12 +116,14 @@
<attr name="title" format="reference" />
<attr name="uri" format="string" />
</declare-styleable>
+
<declare-styleable name="Extra">
<attr name="key" format="string" />
<attr name="value" format="string" />
</declare-styleable>
<declare-styleable name="Include">
<attr name="workspace" format="reference" />
+ <attr name="folderItems" format="reference" />
</declare-styleable>
<declare-styleable name="PreloadIconDrawable">
@@ -143,4 +131,8 @@
<attr name="ringOutset" format="dimension" />
<attr name="indicatorSize" format="dimension" />
</declare-styleable>
+
+ <declare-styleable name="InsettableFrameLayout_Layout">
+ <attr name="layout_ignoreInsets" format="boolean" />
+ </declare-styleable>
</resources>
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 29837eaf7..2daf9fe12 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -29,8 +29,6 @@
<color name="appwidget_error_color">#FCCC</color>
- <color name="workspace_all_apps_and_delete_zone_text_color">#CCFFFFFF</color>
- <color name="workspace_all_apps_and_delete_zone_text_shadow_color">#A0000000</color>
<color name="workspace_icon_text_color">#FFF</color>
<color name="quantum_panel_text_color">#FF666666</color>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 2c9e689c6..f12cb57ba 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -25,8 +25,8 @@
<dimen name="dynamic_grid_workspace_page_spacing">8dp</dimen>
<dimen name="dynamic_grid_overview_min_icon_zone_height">80dp</dimen>
<dimen name="dynamic_grid_overview_max_icon_zone_height">120dp</dimen>
- <dimen name="dynamic_grid_overview_bar_item_width">48dp</dimen>
- <dimen name="dynamic_grid_overview_bar_spacer_width">68dp</dimen>
+ <dimen name="dynamic_grid_overview_bar_item_width">80dp</dimen>
+ <dimen name="dynamic_grid_overview_bar_spacer_width">20dp</dimen>
<!-- Cling -->
<dimen name="cling_migration_logo_height">240dp</dimen>
@@ -43,9 +43,6 @@
<!-- QSB -->
<dimen name="toolbar_button_vertical_padding">4dip</dimen>
<dimen name="toolbar_button_horizontal_padding">12dip</dimen>
- <!-- External toolbar icon size (for bounds) -->
- <dimen name="toolbar_external_icon_width">36dp</dimen>
- <dimen name="toolbar_external_icon_height">36dp</dimen>
<!-- AllApps/Customize/AppsCustomize -->
<!-- The height of the tab bar - if this changes, we should update the
@@ -62,6 +59,7 @@
<!-- Drag padding to add to the bottom of drop targets -->
<dimen name="drop_target_drag_padding">14dp</dimen>
+ <dimen name="drop_target_text_size">14sp</dimen>
<!-- Dragging -->
<!-- the area at the edge of the screen that makes the workspace go left
diff --git a/res/values/strings.xml b/res/values/strings.xml
index ff3509bc5..b6f42379d 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -40,8 +40,12 @@
<string name="folder_name"></string>
<!-- Displayed when user selects a shortcut for an app that was uninstalled [CHAR_LIMIT=none]-->
<string name="activity_not_found">App isn\'t installed.</string>
+ <!-- Displayed when user selects a shortcut for an app that is current not available [CHAR_LIMIT=none]-->
+ <string name="activity_not_available">App isn\'t available</string>
<!-- SafeMode shortcut error string -->
<string name="safemode_shortcut_error">Downloaded app disabled in Safe mode</string>
+ <!-- SafeMode widget error string -->
+ <string name="safemode_widget_error">Widgets disabled in Safe mode</string>
<!-- Labels for the tabs in the customize drawer -->
<string name="widgets_tab_label">Widgets</string>
@@ -52,9 +56,6 @@
<!-- AppsCustomize pane -->
<!-- Message to tell the user to press and hold on a widget to add it [CHAR_LIMIT=50] -->
<string name="long_press_widget_to_add">Touch &amp; hold to pick up a widget.</string>
- <!-- Market button text. The market button text is removed in Launcher.java
- in the Phone UI. [CHAR LIMIT=32] -->
- <string name="market">Shop</string>
<!-- The format string for the dimensions of a widget in the drawer -->
<!-- There is a special version of this format string for Farsi -->
<string name="widget_dims_format">%1$d \u00d7 %2$d</string>
@@ -124,17 +125,13 @@ s -->
device. [CHAR_LIMIT=30]-->
<string name="delete_zone_label_all_apps">Uninstall</string>
- <!-- Label for delete drop target. [CHAR_LIMIT=30] -->
+ <!-- Label for delete drop target. [CHAR_LIMIT=20] -->
<string name="delete_target_label">Remove</string>
- <!-- Label for uninstall drop target. [CHAR_LIMIT=30]-->
+ <!-- Label for uninstall drop target. [CHAR_LIMIT=20]-->
<string name="delete_target_uninstall_label">Uninstall</string>
- <!-- Label for the info icon. [CHAR_LIMIT=30] -->
+ <!-- Label for the info icon. [CHAR_LIMIT=20] -->
<string name="info_target_label">App info</string>
- <!-- Accessibility: Search button -->
- <string name="accessibility_search_button">Search</string>
- <!-- Accessibility: Voice Search button -->
- <string name="accessibility_voice_search_button">Voice Search</string>
<!-- Accessibility: AllApps button -->
<string name="accessibility_all_apps_button">Apps</string>
<!-- Accessibility: Delete button -->
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 56a205fd1..77798f174 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -32,10 +32,9 @@
<item name="android:fontFamily">sans-serif-condensed</item>
</style>
- <style name="WorkspaceIcon.Portrait">
- </style>
- <style name="WorkspaceIcon.Landscape">
- </style>
+ <style name="WorkspaceIcon.Portrait"></style>
+
+ <style name="WorkspaceIcon.Landscape"></style>
<style name="WorkspaceIcon.AppsCustomize">
<item name="android:background">@null</item>
@@ -52,15 +51,14 @@
<item name="customShadows">false</item>
</style>
- <style name="SearchDropTargetBar">
- </style>
- <style name="SearchButton">
- </style>
+ <style name="SearchButton"></style>
+
<style name="DropTargetButtonContainer">
<item name="android:layout_width">0dp</item>
<item name="android:layout_height">match_parent</item>
</style>
- <style name="DropTargetButton">
+
+ <style name="DropTargetButton.Base">
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">match_parent</item>
<item name="android:layout_gravity">center</item>
@@ -69,7 +67,7 @@
<item name="android:paddingLeft">25dp</item>
<item name="android:paddingRight">25dp</item>
<item name="android:textColor">#FFFFFFFF</item>
- <item name="android:textSize">16sp</item>
+ <item name="android:textSize">@dimen/drop_target_text_size</item>
<item name="android:singleLine">true</item>
<item name="android:ellipsize">end</item>
<item name="android:shadowColor">#FF000000</item>
@@ -78,34 +76,7 @@
<item name="android:shadowRadius">4.0</item>
</style>
- <style name="TabIndicator">
- <item name="android:layout_width">wrap_content</item>
- <item name="android:layout_height">match_parent</item>
- <item name="android:gravity">center</item>
- <item name="android:paddingLeft">20dp</item>
- <item name="android:paddingRight">20dp</item>
- <item name="android:background">@drawable/tab_widget_indicator_selector</item>
- <item name="android:textColor">?android:attr/textColorPrimary</item>
- <item name="android:textSize">12sp</item>
- <item name="android:textStyle">bold</item>
- <item name="android:textAllCaps">true</item>
- <item name="android:singleLine">true</item>
- <item name="android:ellipsize">end</item>
- </style>
- <style name="TabIndicator.AppsCustomize">
- <!-- Overridden in values-land -->
- </style>
-
- <style name="MarketButton">
- <item name="android:paddingLeft">5dp</item>
- <item name="android:paddingRight">5dp</item>
- <item name="android:textColor">@color/workspace_all_apps_and_delete_zone_text_color</item>
- <item name="android:textSize">18sp</item>
- <item name="android:shadowColor">@color/workspace_all_apps_and_delete_zone_text_shadow_color</item>
- <item name="android:shadowDx">0.0</item>
- <item name="android:shadowDy">0.0</item>
- <item name="android:shadowRadius">2.0</item>
- </style>
+ <style name="DropTargetButton" parent="DropTargetButton.Base"></style>
<style name="PreloadIcon">
<item name="background">@drawable/virtual_preload</item>
@@ -123,7 +94,5 @@
<style name="PagedViewWidgetImageView">
<item name="android:paddingLeft">@dimen/app_widget_preview_padding_left</item>
</style>
- <style name="SearchButton.WithPaddingStart">
- <item name="android:paddingLeft">8dp</item>
- </style>
+
</resources>
diff --git a/res/xml/default_workspace_4x4_no_all_apps.xml b/res/xml/default_workspace_4x4_no_all_apps.xml
deleted file mode 100644
index 7e1301cef..000000000
--- a/res/xml/default_workspace_4x4_no_all_apps.xml
+++ /dev/null
@@ -1,56 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 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.
--->
-
-<favorites xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3">
- <!-- Hotseat (We use the screen as the position of the item in the hotseat) -->
- <!-- Dialer Hangouts Maps Chrome Camera -->
- <favorite
- launcher:packageName="com.google.android.dialer"
- launcher:className="com.google.android.dialer.extensions.GoogleDialtactsActivity"
- launcher:container="-101"
- launcher:screen="0"
- launcher:x="0"
- launcher:y="0" />
- <favorite
- launcher:packageName="com.google.android.talk"
- launcher:className="com.google.android.talk.SigningInActivity"
- launcher:container="-101"
- launcher:screen="1"
- launcher:x="1"
- launcher:y="0" />
- <favorite
- launcher:packageName="com.google.android.apps.maps"
- launcher:className="com.google.android.maps.MapsActivity"
- launcher:container="-101"
- launcher:screen="2"
- launcher:x="2"
- launcher:y="0"/>
- <favorite
- launcher:packageName="com.android.chrome"
- launcher:className="com.google.android.apps.chrome.Main"
- launcher:container="-101"
- launcher:screen="3"
- launcher:x="3"
- launcher:y="0" />
- <favorite
- launcher:packageName="com.google.android.GoogleCamera"
- launcher:className="com.android.camera.CameraLauncher"
- launcher:container="-101"
- launcher:screen="4"
- launcher:x="4"
- launcher:y="0" />
-</favorites>
-
diff --git a/res/xml/default_workspace_5x5_no_all_apps.xml b/res/xml/default_workspace_5x5_no_all_apps.xml
deleted file mode 100644
index f54a20425..000000000
--- a/res/xml/default_workspace_5x5_no_all_apps.xml
+++ /dev/null
@@ -1,56 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 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.
--->
-
-<favorites xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3">
- <!-- Hotseat (We use the screen as the position of the item in the hotseat) -->
- <!-- Dialer Hangouts Maps Chrome Camera -->
- <favorite
- launcher:packageName="com.google.android.dialer"
- launcher:className="com.google.android.dialer.extensions.GoogleDialtactsActivity"
- launcher:container="-101"
- launcher:screen="1"
- launcher:x="1"
- launcher:y="0" />
- <favorite
- launcher:packageName="com.google.android.talk"
- launcher:className="com.google.android.talk.SigningInActivity"
- launcher:container="-101"
- launcher:screen="2"
- launcher:x="2"
- launcher:y="0" />
- <favorite
- launcher:packageName="com.google.android.apps.maps"
- launcher:className="com.google.android.maps.MapsActivity"
- launcher:container="-101"
- launcher:screen="3"
- launcher:x="3"
- launcher:y="0"/>
- <favorite
- launcher:packageName="com.android.chrome"
- launcher:className="com.google.android.apps.chrome.Main"
- launcher:container="-101"
- launcher:screen="4"
- launcher:x="4"
- launcher:y="0" />
- <favorite
- launcher:packageName="com.google.android.GoogleCamera"
- launcher:className="com.android.camera.CameraLauncher"
- launcher:container="-101"
- launcher:screen="5"
- launcher:x="5"
- launcher:y="0" />
-</favorites>
-
diff --git a/res/xml/default_workspace_5x6_no_all_apps.xml b/res/xml/default_workspace_5x6_no_all_apps.xml
deleted file mode 100644
index f54a20425..000000000
--- a/res/xml/default_workspace_5x6_no_all_apps.xml
+++ /dev/null
@@ -1,56 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 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.
--->
-
-<favorites xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3">
- <!-- Hotseat (We use the screen as the position of the item in the hotseat) -->
- <!-- Dialer Hangouts Maps Chrome Camera -->
- <favorite
- launcher:packageName="com.google.android.dialer"
- launcher:className="com.google.android.dialer.extensions.GoogleDialtactsActivity"
- launcher:container="-101"
- launcher:screen="1"
- launcher:x="1"
- launcher:y="0" />
- <favorite
- launcher:packageName="com.google.android.talk"
- launcher:className="com.google.android.talk.SigningInActivity"
- launcher:container="-101"
- launcher:screen="2"
- launcher:x="2"
- launcher:y="0" />
- <favorite
- launcher:packageName="com.google.android.apps.maps"
- launcher:className="com.google.android.maps.MapsActivity"
- launcher:container="-101"
- launcher:screen="3"
- launcher:x="3"
- launcher:y="0"/>
- <favorite
- launcher:packageName="com.android.chrome"
- launcher:className="com.google.android.apps.chrome.Main"
- launcher:container="-101"
- launcher:screen="4"
- launcher:x="4"
- launcher:y="0" />
- <favorite
- launcher:packageName="com.google.android.GoogleCamera"
- launcher:className="com.android.camera.CameraLauncher"
- launcher:container="-101"
- launcher:screen="5"
- launcher:x="5"
- launcher:y="0" />
-</favorites>
-
diff --git a/src/com/android/launcher3/AccessibleTabView.java b/src/com/android/launcher3/AccessibleTabView.java
deleted file mode 100644
index 90a78656e..000000000
--- a/src/com/android/launcher3/AccessibleTabView.java
+++ /dev/null
@@ -1,51 +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.launcher3;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.KeyEvent;
-import android.widget.TextView;
-
-/**
- * We use a custom tab view to process our own focus traversals.
- */
-public class AccessibleTabView extends TextView {
- public AccessibleTabView(Context context) {
- super(context);
- }
-
- public AccessibleTabView(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- public AccessibleTabView(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- }
-
- @Override
- public boolean onKeyDown(int keyCode, KeyEvent event) {
- return FocusHelper.handleTabKeyEvent(this, keyCode, event)
- || super.onKeyDown(keyCode, event);
- }
-
- @Override
- public boolean onKeyUp(int keyCode, KeyEvent event) {
- return FocusHelper.handleTabKeyEvent(this, keyCode, event)
- || super.onKeyUp(keyCode, event);
- }
-}
diff --git a/src/com/android/launcher3/AllAppsList.java b/src/com/android/launcher3/AllAppsList.java
index 38d2fa541..72c6693b3 100644
--- a/src/com/android/launcher3/AllAppsList.java
+++ b/src/com/android/launcher3/AllAppsList.java
@@ -18,10 +18,6 @@ package com.android.launcher3;
import android.content.ComponentName;
import android.content.Context;
-import android.content.Intent;
-import android.content.pm.ActivityInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
import com.android.launcher3.compat.LauncherActivityInfoCompat;
import com.android.launcher3.compat.LauncherAppsCompat;
@@ -101,17 +97,15 @@ class AllAppsList {
final List<LauncherActivityInfoCompat> matches = launcherApps.getActivityList(packageName,
user);
- if (matches.size() > 0) {
- for (LauncherActivityInfoCompat info : matches) {
- add(new AppInfo(context, info, user, mIconCache, null));
- }
+ for (LauncherActivityInfoCompat info : matches) {
+ add(new AppInfo(context, info, user, mIconCache, null));
}
}
/**
* Remove the apps for the given apk identified by packageName.
*/
- public void removePackage(String packageName, UserHandleCompat user) {
+ public void removePackage(String packageName, UserHandleCompat user, boolean clearCache) {
final List<AppInfo> data = this.data;
for (int i = data.size() - 1; i >= 0; i--) {
AppInfo info = data.get(i);
@@ -121,7 +115,9 @@ class AllAppsList {
data.remove(i);
}
}
- mIconCache.remove(packageName, user);
+ if (clearCache) {
+ mIconCache.remove(packageName, user);
+ }
}
/**
@@ -149,9 +145,7 @@ class AllAppsList {
// Find enabled activities and add them to the adapter
// Also updates existing activities with new labels/icons
- int count = matches.size();
- for (int i = 0; i < count; i++) {
- final LauncherActivityInfoCompat info = matches.get(i);
+ for (final LauncherActivityInfoCompat info : matches) {
AppInfo applicationInfo = findApplicationInfoLocked(
info.getComponentName().getPackageName(), user,
info.getComponentName().getClassName());
diff --git a/src/com/android/launcher3/AppInfo.java b/src/com/android/launcher3/AppInfo.java
index bfcad84b3..a66bac08a 100644
--- a/src/com/android/launcher3/AppInfo.java
+++ b/src/com/android/launcher3/AppInfo.java
@@ -84,16 +84,11 @@ public class AppInfo extends ItemInfo {
flags = initFlags(info);
firstInstallTime = info.getFirstInstallTime();
iconCache.getTitleAndIcon(this, info, labelCache);
- intent = new Intent(Intent.ACTION_MAIN);
- intent.addCategory(Intent.CATEGORY_LAUNCHER);
- intent.setComponent(info.getComponentName());
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
- long serialNumber = UserManagerCompat.getInstance(context).getSerialNumberForUser(user);
- intent.putExtra(EXTRA_PROFILE, serialNumber);
+ intent = makeLaunchIntent(context, info, user);
this.user = user;
}
- private static int initFlags(LauncherActivityInfoCompat info) {
+ public static int initFlags(LauncherActivityInfoCompat info) {
int appFlags = info.getApplicationInfo().flags;
int flags = 0;
if ((appFlags & android.content.pm.ApplicationInfo.FLAG_SYSTEM) == 0) {
@@ -137,4 +132,14 @@ public class AppInfo extends ItemInfo {
public ShortcutInfo makeShortcut() {
return new ShortcutInfo(this);
}
+
+ public static Intent makeLaunchIntent(Context context, LauncherActivityInfoCompat info,
+ UserHandleCompat user) {
+ long serialNumber = UserManagerCompat.getInstance(context).getSerialNumberForUser(user);
+ return new Intent(Intent.ACTION_MAIN)
+ .addCategory(Intent.CATEGORY_LAUNCHER)
+ .setComponent(info.getComponentName())
+ .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED)
+ .putExtra(EXTRA_PROFILE, serialNumber);
+ }
}
diff --git a/src/com/android/launcher3/AppsCustomizePagedView.java b/src/com/android/launcher3/AppsCustomizePagedView.java
index 1bd290777..c8187f068 100644
--- a/src/com/android/launcher3/AppsCustomizePagedView.java
+++ b/src/com/android/launcher3/AppsCustomizePagedView.java
@@ -366,11 +366,7 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen
// This code triggers requestLayout so must be posted outside of the
// layout pass.
public void run() {
- boolean attached = true;
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
- attached = isAttachedToWindow();
- }
- if (attached) {
+ if (Utilities.isViewAttachedToWindow(AppsCustomizePagedView.this)) {
setDataIsReady();
onDataReady(getMeasuredWidth(), getMeasuredHeight());
}
@@ -728,7 +724,8 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen
!(target instanceof DeleteDropTarget) && !(target instanceof Folder))) {
// Exit spring loaded mode if we have not successfully dropped or have not handled the
// drop in Workspace
- mLauncher.exitSpringLoadedDragMode();
+ mLauncher.exitSpringLoadedDragModeDelayed(true,
+ Launcher.EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT, null);
mLauncher.unlockScreenOrientation(false);
} else {
mLauncher.unlockScreenOrientation(false);
@@ -842,6 +839,12 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen
cancelAllTasks();
}
+ @Override
+ public void trimMemory() {
+ super.trimMemory();
+ clearAllWidgetPages();
+ }
+
public void clearAllWidgetPages() {
cancelAllTasks();
int count = getChildCount();
diff --git a/src/com/android/launcher3/AppsCustomizeTabHost.java b/src/com/android/launcher3/AppsCustomizeTabHost.java
index 9a516fd41..a2717126d 100644
--- a/src/com/android/launcher3/AppsCustomizeTabHost.java
+++ b/src/com/android/launcher3/AppsCustomizeTabHost.java
@@ -16,27 +16,13 @@
package com.android.launcher3;
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.AnimatorSet;
-import android.animation.ObjectAnimator;
import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Color;
import android.graphics.Rect;
import android.util.AttributeSet;
-import android.view.LayoutInflater;
-import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.accessibility.AccessibilityManager;
import android.widget.FrameLayout;
-import android.widget.LinearLayout;
-import android.widget.TabHost;
-import android.widget.TabWidget;
-import android.widget.TextView;
-
-import java.util.ArrayList;
public class AppsCustomizeTabHost extends FrameLayout implements LauncherTransitionable, Insettable {
static final String LOG_TAG = "AppsCustomizeTabHost";
@@ -132,6 +118,10 @@ public class AppsCustomizeTabHost extends FrameLayout implements LauncherTransit
mPagedView.reset();
}
+ void trimMemory() {
+ mPagedView.trimMemory();
+ }
+
public void onWindowVisible() {
if (getVisibility() == VISIBLE) {
mContent.setVisibility(VISIBLE);
@@ -141,14 +131,6 @@ public class AppsCustomizeTabHost extends FrameLayout implements LauncherTransit
mPagedView.loadAssociatedPages(mPagedView.getCurrentPage());
}
}
-
- public void onTrimMemory() {
- mContent.setVisibility(GONE);
- // Clear the widget pages of all their subviews - this will trigger the widget previews
- // to delete their bitmaps
- mPagedView.clearAllWidgetPages();
- }
-
@Override
public ViewGroup getContent() {
return mPagedView;
diff --git a/src/com/android/launcher3/AutoInstallsLayout.java b/src/com/android/launcher3/AutoInstallsLayout.java
index 00f0cf36f..a5d22286d 100644
--- a/src/com/android/launcher3/AutoInstallsLayout.java
+++ b/src/com/android/launcher3/AutoInstallsLayout.java
@@ -36,7 +36,6 @@ import android.util.Pair;
import android.util.Patterns;
import com.android.launcher3.LauncherProvider.SqlArguments;
-import com.android.launcher3.LauncherProvider.WorkspaceLoader;
import com.android.launcher3.LauncherSettings.Favorites;
import org.xmlpull.v1.XmlPullParser;
@@ -47,13 +46,11 @@ import java.util.ArrayList;
import java.util.HashMap;
/**
- * This class contains contains duplication of functionality as found in
- * LauncherProvider#DatabaseHelper. It has been isolated and differentiated in order
- * to cleanly and separately represent AutoInstall default layout format and policy.
+ * Layout parsing code for auto installs layout
*/
-public class AutoInstallsLayout implements WorkspaceLoader {
+public class AutoInstallsLayout {
private static final String TAG = "AutoInstalls";
- private static final boolean LOGD = true;
+ private static final boolean LOGD = false;
/** Marker action used to discover a package which defines launcher customization */
static final String ACTION_LAUNCHER_CUSTOMIZATION =
@@ -76,7 +73,8 @@ public class AutoInstallsLayout implements WorkspaceLoader {
Log.e(TAG, "Layout definition not found in package: " + pkg);
return null;
}
- return new AutoInstallsLayout(context, appWidgetHost, callback, pkg, res, layoutId);
+ return new AutoInstallsLayout(context, appWidgetHost, callback, res, layoutId,
+ TAG_WORKSPACE);
}
// Object Tags
@@ -116,45 +114,55 @@ public class AutoInstallsLayout implements WorkspaceLoader {
private final AppWidgetHost mAppWidgetHost;
private final LayoutParserCallback mCallback;
- private final PackageManager mPackageManager;
- private final ContentValues mValues;
+ protected final PackageManager mPackageManager;
+ protected final Resources mSourceRes;
+ protected final int mLayoutId;
+
+ private final int mHotseatAllAppsRank;
- private final Resources mRes;
- private final int mLayoutId;
+ private final long[] mTemp = new long[2];
+ private final ContentValues mValues;
+ private final String mRootTag;
- private SQLiteDatabase mDb;
+ protected SQLiteDatabase mDb;
public AutoInstallsLayout(Context context, AppWidgetHost appWidgetHost,
- LayoutParserCallback callback, String packageName, Resources res, int layoutId) {
+ LayoutParserCallback callback, Resources res,
+ int layoutId, String rootTag) {
mContext = context;
mAppWidgetHost = appWidgetHost;
mCallback = callback;
mPackageManager = context.getPackageManager();
mValues = new ContentValues();
+ mRootTag = rootTag;
- mRes = res;
+ mSourceRes = res;
mLayoutId = layoutId;
+ mHotseatAllAppsRank = LauncherAppState.getInstance()
+ .getDynamicGrid().getDeviceProfile().hotseatAllAppsRank;
}
- @Override
+ /**
+ * Loads the layout in the db and returns the number of entries added on the desktop.
+ */
public int loadLayout(SQLiteDatabase db, ArrayList<Long> screenIds) {
mDb = db;
try {
- return parseLayout(mRes, mLayoutId, screenIds);
- } catch (XmlPullParserException | IOException | RuntimeException e) {
+ return parseLayout(mLayoutId, screenIds);
+ } catch (Exception e) {
Log.w(TAG, "Got exception parsing layout.", e);
return -1;
}
}
- private int parseLayout(Resources res, int layoutId, ArrayList<Long> screenIds)
+ /**
+ * Parses the layout and returns the number of elements added on the homescreen.
+ */
+ protected int parseLayout(int layoutId, ArrayList<Long> screenIds)
throws XmlPullParserException, IOException {
- final int hotseatAllAppsRank = LauncherAppState.getInstance()
- .getDynamicGrid().getDeviceProfile().hotseatAllAppsRank;
-
- XmlResourceParser parser = res.getXml(layoutId);
- beginDocument(parser, TAG_WORKSPACE);
+ XmlResourceParser parser = mSourceRes.getXml(layoutId);
+ beginDocument(parser, mRootTag);
final int depth = parser.getDepth();
int type;
HashMap<String, TagParser> tagParserMap = getLayoutElementsMap();
@@ -165,45 +173,60 @@ public class AutoInstallsLayout implements WorkspaceLoader {
if (type != XmlPullParser.START_TAG) {
continue;
}
+ count += parseAndAddNode(parser, tagParserMap, screenIds);
+ }
+ return count;
+ }
- mValues.clear();
- final int container;
- final long screenId;
-
- if (HOTSEAT_CONTAINER_NAME.equals(getAttributeValue(parser, ATTR_CONTAINER))) {
- container = Favorites.CONTAINER_HOTSEAT;
-
- // Hack: hotseat items are stored using screen ids
- long rank = Long.parseLong(getAttributeValue(parser, ATTR_RANK));
- screenId = (rank < hotseatAllAppsRank) ? rank : (rank + 1);
-
- } else {
- container = Favorites.CONTAINER_DESKTOP;
- screenId = Long.parseLong(getAttributeValue(parser, ATTR_SCREEN));
-
- mValues.put(Favorites.CELLX, getAttributeValue(parser, ATTR_X));
- mValues.put(Favorites.CELLY, getAttributeValue(parser, ATTR_Y));
- }
-
- mValues.put(Favorites.CONTAINER, container);
- mValues.put(Favorites.SCREEN, screenId);
+ /**
+ * Parses container and screenId attribute from the current tag, and puts it in the out.
+ * @param out array of size 2.
+ */
+ protected void parseContainerAndScreen(XmlResourceParser parser, long[] out) {
+ if (HOTSEAT_CONTAINER_NAME.equals(getAttributeValue(parser, ATTR_CONTAINER))) {
+ out[0] = Favorites.CONTAINER_HOTSEAT;
+ // Hack: hotseat items are stored using screen ids
+ long rank = Long.parseLong(getAttributeValue(parser, ATTR_RANK));
+ out[1] = (rank < mHotseatAllAppsRank) ? rank : (rank + 1);
+ } else {
+ out[0] = Favorites.CONTAINER_DESKTOP;
+ out[1] = Long.parseLong(getAttributeValue(parser, ATTR_SCREEN));
+ }
+ }
- TagParser tagParser = tagParserMap.get(parser.getName());
- if (tagParser == null) {
- if (LOGD) Log.d(TAG, "Ignoring unknown element tag: " + parser.getName());
- continue;
- }
- long newElementId = tagParser.parseAndAdd(parser, res);
- if (newElementId >= 0) {
- // Keep track of the set of screens which need to be added to the db.
- if (!screenIds.contains(screenId) &&
- container == Favorites.CONTAINER_DESKTOP) {
- screenIds.add(screenId);
- }
- count++;
+ /**
+ * Parses the current node and returns the number of elements added.
+ */
+ protected int parseAndAddNode(
+ XmlResourceParser parser,
+ HashMap<String, TagParser> tagParserMap,
+ ArrayList<Long> screenIds)
+ throws XmlPullParserException, IOException {
+ mValues.clear();
+ parseContainerAndScreen(parser, mTemp);
+ final long container = mTemp[0];
+ final long screenId = mTemp[1];
+
+ mValues.put(Favorites.CONTAINER, container);
+ mValues.put(Favorites.SCREEN, screenId);
+ mValues.put(Favorites.CELLX, getAttributeValue(parser, ATTR_X));
+ mValues.put(Favorites.CELLY, getAttributeValue(parser, ATTR_Y));
+
+ TagParser tagParser = tagParserMap.get(parser.getName());
+ if (tagParser == null) {
+ if (LOGD) Log.d(TAG, "Ignoring unknown element tag: " + parser.getName());
+ return 0;
+ }
+ long newElementId = tagParser.parseAndAdd(parser);
+ if (newElementId >= 0) {
+ // Keep track of the set of screens which need to be added to the db.
+ if (!screenIds.contains(screenId) &&
+ container == Favorites.CONTAINER_DESKTOP) {
+ screenIds.add(screenId);
}
+ return 1;
}
- return count;
+ return 0;
}
protected long addShortcut(String title, Intent intent, int type) {
@@ -225,7 +248,7 @@ public class AutoInstallsLayout implements WorkspaceLoader {
HashMap<String, TagParser> parsers = new HashMap<String, TagParser>();
parsers.put(TAG_APP_ICON, new AppShortcutParser());
parsers.put(TAG_AUTO_INSTALL, new AutoInstallParser());
- parsers.put(TAG_SHORTCUT, new ShortcutParser());
+ parsers.put(TAG_SHORTCUT, new ShortcutParser(mSourceRes));
return parsers;
}
@@ -235,23 +258,26 @@ public class AutoInstallsLayout implements WorkspaceLoader {
parsers.put(TAG_AUTO_INSTALL, new AutoInstallParser());
parsers.put(TAG_FOLDER, new FolderParser());
parsers.put(TAG_APPWIDGET, new AppWidgetParser());
- parsers.put(TAG_SHORTCUT, new ShortcutParser());
+ parsers.put(TAG_SHORTCUT, new ShortcutParser(mSourceRes));
return parsers;
}
- private interface TagParser {
+ protected interface TagParser {
/**
* Parses the tag and adds to the db
* @return the id of the row added or -1;
*/
- long parseAndAdd(XmlResourceParser parser, Resources res)
+ long parseAndAdd(XmlResourceParser parser)
throws XmlPullParserException, IOException;
}
- private class AppShortcutParser implements TagParser {
+ /**
+ * App shortcuts: required attributes packageName and className
+ */
+ protected class AppShortcutParser implements TagParser {
@Override
- public long parseAndAdd(XmlResourceParser parser, Resources res) {
+ public long parseAndAdd(XmlResourceParser parser) {
final String packageName = getAttributeValue(parser, ATTR_PACKAGE_NAME);
final String className = getAttributeValue(parser, ATTR_CLASS_NAME);
@@ -277,20 +303,30 @@ public class AutoInstallsLayout implements WorkspaceLoader {
return addShortcut(info.loadLabel(mPackageManager).toString(),
intent, Favorites.ITEM_TYPE_APPLICATION);
} catch (PackageManager.NameNotFoundException e) {
- Log.w(TAG, "Unable to add favorite: " + packageName + "/" + className, e);
+ if (LOGD) Log.w(TAG, "Unable to add favorite: " + packageName + "/" + className, e);
}
return -1;
} else {
- if (LOGD) Log.d(TAG, "Skipping invalid <favorite> with no component or uri");
- return -1;
+ return invalidPackageOrClass(parser);
}
}
+
+ /**
+ * Helper method to allow extending the parser capabilities
+ */
+ protected long invalidPackageOrClass(XmlResourceParser parser) {
+ if (LOGD) Log.d(TAG, "Skipping invalid <favorite> with no component");
+ return -1;
+ }
}
- private class AutoInstallParser implements TagParser {
+ /**
+ * AutoInstall: required attributes packageName and className
+ */
+ protected class AutoInstallParser implements TagParser {
@Override
- public long parseAndAdd(XmlResourceParser parser, Resources res) {
+ public long parseAndAdd(XmlResourceParser parser) {
final String packageName = getAttributeValue(parser, ATTR_PACKAGE_NAME);
final String className = getAttributeValue(parser, ATTR_CLASS_NAME);
if (TextUtils.isEmpty(packageName) || TextUtils.isEmpty(className)) {
@@ -309,11 +345,19 @@ public class AutoInstallsLayout implements WorkspaceLoader {
}
}
- private class ShortcutParser implements TagParser {
+ /**
+ * Parses a web shortcut. Required attributes url, icon, title
+ */
+ protected class ShortcutParser implements TagParser {
+
+ private final Resources mIconRes;
+
+ public ShortcutParser(Resources iconRes) {
+ mIconRes = iconRes;
+ }
@Override
- public long parseAndAdd(XmlResourceParser parser, Resources res) {
- final String url = getAttributeValue(parser, ATTR_URL);
+ public long parseAndAdd(XmlResourceParser parser) {
final int titleResId = getAttributeResourceValue(parser, ATTR_TITLE, 0);
final int iconId = getAttributeResourceValue(parser, ATTR_ICON, 0);
@@ -322,29 +366,46 @@ public class AutoInstallsLayout implements WorkspaceLoader {
return -1;
}
- if (TextUtils.isEmpty(url) || !Patterns.WEB_URL.matcher(url).matches()) {
- if (LOGD) Log.d(TAG, "Ignoring shortcut, invalid url: " + url);
+ final Intent intent = parseIntent(parser);
+ if (intent == null) {
return -1;
}
- Drawable icon = res.getDrawable(iconId);
+
+ Drawable icon = mIconRes.getDrawable(iconId);
if (icon == null) {
if (LOGD) Log.d(TAG, "Ignoring shortcut, can't load icon");
return -1;
}
ItemInfo.writeBitmap(mValues, Utilities.createIconBitmap(icon, mContext));
- final Intent intent = new Intent(Intent.ACTION_VIEW, null)
- .setData(Uri.parse(url))
- .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
+ mValues.put(Favorites.ICON_TYPE, Favorites.ICON_TYPE_RESOURCE);
+ mValues.put(Favorites.ICON_PACKAGE, mIconRes.getResourcePackageName(iconId));
+ mValues.put(Favorites.ICON_RESOURCE, mIconRes.getResourceName(iconId));
+
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
- return addShortcut(res.getString(titleResId), intent, Favorites.ITEM_TYPE_SHORTCUT);
+ return addShortcut(mSourceRes.getString(titleResId),
+ intent, Favorites.ITEM_TYPE_SHORTCUT);
+ }
+
+ protected Intent parseIntent(XmlResourceParser parser) {
+ final String url = getAttributeValue(parser, ATTR_URL);
+ if (TextUtils.isEmpty(url) || !Patterns.WEB_URL.matcher(url).matches()) {
+ if (LOGD) Log.d(TAG, "Ignoring shortcut, invalid url: " + url);
+ return null;
+ }
+ return new Intent(Intent.ACTION_VIEW, null).setData(Uri.parse(url));
}
}
- private class AppWidgetParser implements TagParser {
+ /**
+ * AppWidget parser: Required attributes packageName, className, spanX and spanY.
+ * Options child nodes: <extra key=... value=... />
+ */
+ protected class AppWidgetParser implements TagParser {
@Override
- public long parseAndAdd(XmlResourceParser parser, Resources res)
+ public long parseAndAdd(XmlResourceParser parser)
throws XmlPullParserException, IOException {
final String packageName = getAttributeValue(parser, ATTR_PACKAGE_NAME);
final String className = getAttributeValue(parser, ATTR_CLASS_NAME);
@@ -429,16 +490,24 @@ public class AutoInstallsLayout implements WorkspaceLoader {
}
}
- private class FolderParser implements TagParser {
- private final HashMap<String, TagParser> mFolderElements = getFolderElementsMap();
+ protected class FolderParser implements TagParser {
+ private final HashMap<String, TagParser> mFolderElements;
+
+ public FolderParser() {
+ this(getFolderElementsMap());
+ }
+
+ public FolderParser(HashMap<String, TagParser> elements) {
+ mFolderElements = elements;
+ }
@Override
- public long parseAndAdd(XmlResourceParser parser, Resources res)
+ public long parseAndAdd(XmlResourceParser parser)
throws XmlPullParserException, IOException {
final String title;
final int titleResId = getAttributeResourceValue(parser, ATTR_TITLE, 0);
if (titleResId != 0) {
- title = res.getString(titleResId);
+ title = mSourceRes.getString(titleResId);
} else {
title = mContext.getResources().getString(R.string.folder_name);
}
@@ -469,7 +538,7 @@ public class AutoInstallsLayout implements WorkspaceLoader {
TagParser tagParser = mFolderElements.get(parser.getName());
if (tagParser != null) {
- final long id = tagParser.parseAndAdd(parser, res);
+ final long id = tagParser.parseAndAdd(parser);
if (id >= 0) {
folderItems.add(id);
}
@@ -508,7 +577,7 @@ public class AutoInstallsLayout implements WorkspaceLoader {
}
}
- private static final void beginDocument(XmlPullParser parser, String firstElementName)
+ protected static final void beginDocument(XmlPullParser parser, String firstElementName)
throws XmlPullParserException, IOException {
int type;
while ((type = parser.next()) != XmlPullParser.START_TAG
@@ -528,7 +597,7 @@ public class AutoInstallsLayout implements WorkspaceLoader {
* Return attribute value, attempting launcher-specific namespace first
* before falling back to anonymous attribute.
*/
- private static String getAttributeValue(XmlResourceParser parser, String attribute) {
+ protected static String getAttributeValue(XmlResourceParser parser, String attribute) {
String value = parser.getAttributeValue(
"http://schemas.android.com/apk/res-auto/com.android.launcher3", attribute);
if (value == null) {
@@ -541,7 +610,7 @@ public class AutoInstallsLayout implements WorkspaceLoader {
* Return attribute resource value, attempting launcher-specific namespace
* first before falling back to anonymous attribute.
*/
- private static int getAttributeResourceValue(XmlResourceParser parser, String attribute,
+ protected static int getAttributeResourceValue(XmlResourceParser parser, String attribute,
int defaultValue) {
int value = parser.getAttributeResourceValue(
"http://schemas.android.com/apk/res-auto/com.android.launcher3", attribute,
diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java
index a368796bd..07f3045a5 100644
--- a/src/com/android/launcher3/BubbleTextView.java
+++ b/src/com/android/launcher3/BubbleTextView.java
@@ -40,7 +40,7 @@ import android.widget.TextView;
*/
public class BubbleTextView extends TextView {
- private static SparseArray<Theme> sPreloaderThemes = new SparseArray<>(2);
+ private static SparseArray<Theme> sPreloaderThemes = new SparseArray<Theme>(2);
private static final float SHADOW_LARGE_RADIUS = 4.0f;
private static final float SHADOW_SMALL_RADIUS = 1.75f;
@@ -122,7 +122,7 @@ public class BubbleTextView extends TextView {
LauncherAppState app = LauncherAppState.getInstance();
FastBitmapDrawable iconDrawable = Utilities.createIconDrawable(b);
- iconDrawable.setGhostModeEnabled(info.isDisabled);
+ iconDrawable.setGhostModeEnabled(info.isDisabled != 0);
setCompoundDrawables(null, iconDrawable, null, null);
if (setDefaultPadding) {
diff --git a/src/com/android/launcher3/DefaultLayoutParser.java b/src/com/android/launcher3/DefaultLayoutParser.java
new file mode 100644
index 000000000..e3ea40ebb
--- /dev/null
+++ b/src/com/android/launcher3/DefaultLayoutParser.java
@@ -0,0 +1,290 @@
+package com.android.launcher3;
+
+import android.appwidget.AppWidgetHost;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.res.Resources;
+import android.content.res.XmlResourceParser;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.android.launcher3.LauncherSettings.Favorites;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * Implements the layout parser with rules for internal layouts and partner layouts.
+ */
+public class DefaultLayoutParser extends AutoInstallsLayout {
+ private static final String TAG = "DefaultLayoutParser";
+
+ private static final String TAG_RESOLVE = "resolve";
+ private static final String TAG_FAVORITES = "favorites";
+ private static final String TAG_FAVORITE = "favorite";
+ private static final String TAG_APPWIDGET = "appwidget";
+ private static final String TAG_SHORTCUT = "shortcut";
+ private static final String TAG_FOLDER = "folder";
+ private static final String TAG_PARTNER_FOLDER = "partner-folder";
+ private static final String TAG_INCLUDE = "include";
+
+ private static final String ATTR_URI = "uri";
+ private static final String ATTR_WORKSPACE = "workspace";
+ private static final String ATTR_CONTAINER = "container";
+ private static final String ATTR_SCREEN = "screen";
+ private static final String ATTR_FOLDER_ITEMS = "folderItems";
+
+ public DefaultLayoutParser(Context context, AppWidgetHost appWidgetHost,
+ LayoutParserCallback callback, Resources sourceRes, int layoutId) {
+ super(context, appWidgetHost, callback, sourceRes, layoutId, TAG_FAVORITES);
+ Log.e(TAG, "Default layout parser initialized");
+ }
+
+ @Override
+ protected HashMap<String, TagParser> getFolderElementsMap() {
+ return getFolderElementsMap(mSourceRes);
+ }
+
+ private HashMap<String, TagParser> getFolderElementsMap(Resources res) {
+ HashMap<String, TagParser> parsers = new HashMap<String, TagParser>();
+ parsers.put(TAG_FAVORITE, new AppShortcutWithUriParser());
+ parsers.put(TAG_SHORTCUT, new UriShortcutParser(res));
+ return parsers;
+ }
+
+ @Override
+ protected HashMap<String, TagParser> getLayoutElementsMap() {
+ HashMap<String, TagParser> parsers = new HashMap<String, TagParser>();
+ parsers.put(TAG_FAVORITE, new AppShortcutWithUriParser());
+ parsers.put(TAG_APPWIDGET, new AppWidgetParser());
+ parsers.put(TAG_SHORTCUT, new UriShortcutParser(mSourceRes));
+ parsers.put(TAG_RESOLVE, new ResolveParser());
+ parsers.put(TAG_FOLDER, new MyFolderParser());
+ parsers.put(TAG_PARTNER_FOLDER, new PartnerFolderParser());
+ return parsers;
+ }
+
+ @Override
+ protected void parseContainerAndScreen(XmlResourceParser parser, long[] out) {
+ out[0] = LauncherSettings.Favorites.CONTAINER_DESKTOP;
+ String strContainer = getAttributeValue(parser, ATTR_CONTAINER);
+ if (strContainer != null) {
+ out[0] = Long.valueOf(strContainer);
+ }
+ out[1] = Long.parseLong(getAttributeValue(parser, ATTR_SCREEN));
+ }
+
+ @Override
+ protected int parseAndAddNode(
+ XmlResourceParser parser,
+ HashMap<String, TagParser> tagParserMap,
+ ArrayList<Long> screenIds)
+ throws XmlPullParserException, IOException {
+ if (TAG_INCLUDE.equals(parser.getName())) {
+ final int resId = getAttributeResourceValue(parser, ATTR_WORKSPACE, 0);
+ if (resId != 0) {
+ // recursively load some more favorites, why not?
+ return parseLayout(resId, screenIds);
+ } else {
+ return 0;
+ }
+ } else {
+ return super.parseAndAddNode(parser, tagParserMap, screenIds);
+ }
+ }
+
+ /**
+ * AppShortcutParser which also supports adding URI based intents
+ */
+ private class AppShortcutWithUriParser extends AppShortcutParser {
+
+ @Override
+ protected long invalidPackageOrClass(XmlResourceParser parser) {
+ final String uri = getAttributeValue(parser, ATTR_URI);
+ if (TextUtils.isEmpty(uri)) {
+ Log.e(TAG, "Skipping invalid <favorite> with no component or uri");
+ return -1;
+ }
+
+ final Intent metaIntent;
+ try {
+ metaIntent = Intent.parseUri(uri, 0);
+ } catch (URISyntaxException e) {
+ Log.e(TAG, "Unable to add meta-favorite: " + uri, e);
+ return -1;
+ }
+
+ ResolveInfo resolved = mPackageManager.resolveActivity(metaIntent,
+ PackageManager.MATCH_DEFAULT_ONLY);
+ final List<ResolveInfo> appList = mPackageManager.queryIntentActivities(
+ metaIntent, PackageManager.MATCH_DEFAULT_ONLY);
+
+ // Verify that the result is an app and not just the resolver dialog asking which
+ // app to use.
+ if (wouldLaunchResolverActivity(resolved, appList)) {
+ // If only one of the results is a system app then choose that as the default.
+ final ResolveInfo systemApp = getSingleSystemActivity(appList);
+ if (systemApp == null) {
+ // There is no logical choice for this meta-favorite, so rather than making
+ // a bad choice just add nothing.
+ Log.w(TAG, "No preference or single system activity found for "
+ + metaIntent.toString());
+ return -1;
+ }
+ resolved = systemApp;
+ }
+ final ActivityInfo info = resolved.activityInfo;
+ final Intent intent = mPackageManager.getLaunchIntentForPackage(info.packageName);
+ if (intent == null) {
+ return -1;
+ }
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
+ Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
+
+ return addShortcut(info.loadLabel(mPackageManager).toString(), intent,
+ Favorites.ITEM_TYPE_APPLICATION);
+ }
+
+ private ResolveInfo getSingleSystemActivity(List<ResolveInfo> appList) {
+ ResolveInfo systemResolve = null;
+ final int N = appList.size();
+ for (int i = 0; i < N; ++i) {
+ try {
+ ApplicationInfo info = mPackageManager.getApplicationInfo(
+ appList.get(i).activityInfo.packageName, 0);
+ if ((info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
+ if (systemResolve != null) {
+ return null;
+ } else {
+ systemResolve = appList.get(i);
+ }
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.w(TAG, "Unable to get info about resolve results", e);
+ return null;
+ }
+ }
+ return systemResolve;
+ }
+
+ private boolean wouldLaunchResolverActivity(ResolveInfo resolved,
+ List<ResolveInfo> appList) {
+ // If the list contains the above resolved activity, then it can't be
+ // ResolverActivity itself.
+ for (int i = 0; i < appList.size(); ++i) {
+ ResolveInfo tmp = appList.get(i);
+ if (tmp.activityInfo.name.equals(resolved.activityInfo.name)
+ && tmp.activityInfo.packageName.equals(resolved.activityInfo.packageName)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ }
+
+
+ /**
+ * Shortcut parser which allows any uri and not just web urls.
+ */
+ private class UriShortcutParser extends ShortcutParser {
+
+ public UriShortcutParser(Resources iconRes) {
+ super(iconRes);
+ }
+
+ @Override
+ protected Intent parseIntent(XmlResourceParser parser) {
+ String uri = null;
+ try {
+ uri = getAttributeValue(parser, ATTR_URI);
+ return Intent.parseUri(uri, 0);
+ } catch (URISyntaxException e) {
+ Log.w(TAG, "Shortcut has malformed uri: " + uri);
+ return null; // Oh well
+ }
+ }
+ }
+
+ /**
+ * Contains a list of <favorite> nodes, and accepts the first successfully parsed node.
+ */
+ private class ResolveParser implements TagParser {
+
+ private final AppShortcutWithUriParser mChildParser = new AppShortcutWithUriParser();
+
+ @Override
+ public long parseAndAdd(XmlResourceParser parser) throws XmlPullParserException,
+ IOException {
+ final int groupDepth = parser.getDepth();
+ int type;
+ long addedId = -1;
+ while ((type = parser.next()) != XmlPullParser.END_TAG ||
+ parser.getDepth() > groupDepth) {
+ if (type != XmlPullParser.START_TAG || addedId > -1) {
+ continue;
+ }
+ final String fallback_item_name = parser.getName();
+ if (TAG_FAVORITE.equals(fallback_item_name)) {
+ addedId = mChildParser.parseAndAdd(parser);
+ } else {
+ Log.e(TAG, "Fallback groups can contain only favorites, found "
+ + fallback_item_name);
+ }
+ }
+ return addedId;
+ }
+ }
+
+ /**
+ * A parser which adds a folder whose contents come from partner apk.
+ */
+ private class PartnerFolderParser implements TagParser {
+
+ @Override
+ public long parseAndAdd(XmlResourceParser parser) throws XmlPullParserException,
+ IOException {
+ // Folder contents come from an external XML resource
+ final Partner partner = Partner.get(mPackageManager);
+ if (partner != null) {
+ final Resources partnerRes = partner.getResources();
+ final int resId = partnerRes.getIdentifier(Partner.RES_FOLDER,
+ "xml", partner.getPackageName());
+ if (resId != 0) {
+ final XmlResourceParser partnerParser = partnerRes.getXml(resId);
+ beginDocument(partnerParser, TAG_FOLDER);
+
+ FolderParser folderParser = new FolderParser(getFolderElementsMap(partnerRes));
+ return folderParser.parseAndAdd(partnerParser);
+ }
+ }
+ return -1;
+ }
+ }
+
+ /**
+ * An extension of FolderParser which allows adding items from a different xml.
+ */
+ private class MyFolderParser extends FolderParser {
+
+ @Override
+ public long parseAndAdd(XmlResourceParser parser) throws XmlPullParserException,
+ IOException {
+ final int resId = getAttributeResourceValue(parser, ATTR_FOLDER_ITEMS, 0);
+ if (resId != 0) {
+ parser = mSourceRes.getXml(resId);
+ beginDocument(parser, TAG_FOLDER);
+ }
+ return super.parseAndAdd(parser);
+ }
+ }
+}
diff --git a/src/com/android/launcher3/DeleteDropTarget.java b/src/com/android/launcher3/DeleteDropTarget.java
index 05e8906cb..ea058ea71 100644
--- a/src/com/android/launcher3/DeleteDropTarget.java
+++ b/src/com/android/launcher3/DeleteDropTarget.java
@@ -21,8 +21,6 @@ import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.content.ComponentName;
import android.content.Context;
-import android.content.Intent;
-import android.content.pm.ResolveInfo;
import android.content.res.ColorStateList;
import android.content.res.Configuration;
import android.content.res.Resources;
@@ -41,12 +39,8 @@ import android.view.animation.AnimationUtils;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.LinearInterpolator;
-import com.android.launcher3.compat.LauncherAppsCompat;
import com.android.launcher3.compat.UserHandleCompat;
-import java.util.List;
-import java.util.Set;
-
public class DeleteDropTarget extends ButtonDropTarget {
private static int DELETE_ANIMATION_DURATION = 285;
private static int FLING_DELETE_ANIMATION_DURATION = 350;
@@ -266,7 +260,7 @@ public class DeleteDropTarget extends ButtonDropTarget {
public void run() {
completeDrop(d);
mSearchDropTargetBar.onDragEnd();
- mLauncher.exitSpringLoadedDragMode();
+ mLauncher.exitSpringLoadedDragModeDelayed(true, 0, null);
}
};
dragLayer.animateView(d.dragView, from, to, scale, 1f, 1f, 0.1f, 0.1f,
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index daf5556d4..d6aadcee1 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -33,6 +33,7 @@ import android.view.Surface;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
+import android.view.ViewGroup.MarginLayoutParams;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
@@ -75,7 +76,6 @@ public class DeviceProfile {
private float hotseatIconSize;
int defaultLayoutId;
- int defaultNoAllAppsLayoutId;
boolean isLandscape;
boolean isTablet;
@@ -122,9 +122,7 @@ public class DeviceProfile {
int allAppsNumRows;
int allAppsNumCols;
int searchBarSpaceWidthPx;
- int searchBarSpaceMaxWidthPx;
int searchBarSpaceHeightPx;
- int searchBarHeightPx;
int pageIndicatorHeightPx;
int allAppsButtonVisualSize;
@@ -136,7 +134,7 @@ public class DeviceProfile {
private ArrayList<DeviceProfileCallbacks> mCallbacks = new ArrayList<DeviceProfileCallbacks>();
DeviceProfile(String n, float w, float h, float r, float c,
- float is, float its, float hs, float his, int dlId, int dnalId) {
+ float is, float its, float hs, float his, int dlId) {
// Ensure that we have an odd number of hotseat items (since we need to place all apps)
if (!LauncherAppState.isDisableAllApps() && hs % 2 == 0) {
throw new RuntimeException("All Device Profiles must have an odd number of hotseat spaces");
@@ -152,7 +150,6 @@ public class DeviceProfile {
numHotseatIcons = hs;
hotseatIconSize = his;
defaultLayoutId = dlId;
- defaultNoAllAppsLayoutId = dnalId;
}
DeviceProfile() {
@@ -215,9 +212,6 @@ public class DeviceProfile {
// Snap to the closest default layout id
defaultLayoutId = closestProfile.defaultLayoutId;
- // Snap to the closest default no all-apps layout id
- defaultNoAllAppsLayoutId = closestProfile.defaultNoAllAppsLayoutId;
-
// Interpolate the icon size
points.clear();
for (DeviceProfile p : profiles) {
@@ -376,10 +370,10 @@ public class DeviceProfile {
hotseatIconSizePx = (int) (DynamicGrid.pxFromDp(hotseatIconSize, dm) * scale);
// Search Bar
- searchBarSpaceMaxWidthPx = resources.getDimensionPixelSize(R.dimen.dynamic_grid_search_bar_max_width);
- searchBarHeightPx = resources.getDimensionPixelSize(R.dimen.dynamic_grid_search_bar_height);
- searchBarSpaceWidthPx = Math.min(searchBarSpaceMaxWidthPx, widthPx);
- searchBarSpaceHeightPx = searchBarHeightPx + getSearchBarTopOffset();
+ searchBarSpaceWidthPx = Math.min(widthPx,
+ resources.getDimensionPixelSize(R.dimen.dynamic_grid_search_bar_max_width));
+ searchBarSpaceHeightPx = getSearchBarTopOffset()
+ + resources.getDimensionPixelSize(R.dimen.dynamic_grid_search_bar_height);
// Calculate the actual text height
Paint textPaint = new Paint();
@@ -402,10 +396,6 @@ public class DeviceProfile {
folderIconSizePx = iconSizePx + 2 * -folderBackgroundOffset;
// All Apps
- Rect padding = getWorkspacePadding(isLandscape ?
- CellLayout.LANDSCAPE : CellLayout.PORTRAIT);
- int pageIndicatorOffset =
- resources.getDimensionPixelSize(R.dimen.apps_customize_page_indicator_offset);
allAppsCellWidthPx = allAppsIconSizePx;
allAppsCellHeightPx = allAppsIconSizePx + drawablePadding + iconTextSizePx;
int maxLongEdgeCellCount =
@@ -708,11 +698,6 @@ public class DeviceProfile {
return visibleChildren;
}
- int calculateOverviewModeWidth(int visibleChildCount) {
- return visibleChildCount * overviewModeBarItemWidthPx +
- (visibleChildCount-1) * overviewModeBarSpacerWidthPx;
- }
-
public void layout(Launcher launcher) {
FrameLayout.LayoutParams lp;
Resources res = launcher.getResources();
@@ -726,9 +711,6 @@ public class DeviceProfile {
lp.gravity = Gravity.TOP | Gravity.LEFT;
lp.width = searchBarSpaceHeightPx;
lp.height = LayoutParams.WRAP_CONTENT;
- searchBar.setPadding(
- 0, 2 * edgeMarginPx, 0,
- 2 * edgeMarginPx);
LinearLayout targets = (LinearLayout) searchBar.findViewById(R.id.drag_target_bar);
targets.setOrientation(LinearLayout.VERTICAL);
@@ -737,27 +719,9 @@ public class DeviceProfile {
lp.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL;
lp.width = searchBarSpaceWidthPx;
lp.height = searchBarSpaceHeightPx;
- searchBar.setPadding(
- 2 * edgeMarginPx,
- getSearchBarTopOffset(),
- 2 * edgeMarginPx, 0);
}
searchBar.setLayoutParams(lp);
- // Layout the voice proxy
- View voiceButtonProxy = launcher.findViewById(R.id.voice_button_proxy);
- if (voiceButtonProxy != null) {
- if (hasVerticalBarLayout) {
- // TODO: MOVE THIS INTO SEARCH BAR MEASURE
- } else {
- lp = (FrameLayout.LayoutParams) voiceButtonProxy.getLayoutParams();
- lp.gravity = Gravity.TOP | Gravity.END;
- lp.width = (widthPx - searchBarSpaceWidthPx) / 2 +
- 2 * iconSizePx;
- lp.height = searchBarSpaceHeightPx;
- }
- }
-
// Layout the workspace
PagedView workspace = (PagedView) launcher.findViewById(R.id.workspace);
lp = (FrameLayout.LayoutParams) workspace.getLayoutParams();
@@ -877,10 +841,38 @@ public class DeviceProfile {
Rect r = getOverviewModeButtonBarRect();
lp = (FrameLayout.LayoutParams) overviewMode.getLayoutParams();
lp.gravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
- lp.width = Math.min(availableWidthPx,
- calculateOverviewModeWidth(getVisibleChildCount(overviewMode)));
+
+ int visibleChildCount = getVisibleChildCount(overviewMode);
+ int totalItemWidth = visibleChildCount * overviewModeBarItemWidthPx;
+ int maxWidth = totalItemWidth + (visibleChildCount-1) * overviewModeBarSpacerWidthPx;
+
+ lp.width = Math.min(availableWidthPx, maxWidth);
lp.height = r.height();
overviewMode.setLayoutParams(lp);
+
+ if (lp.width > totalItemWidth && visibleChildCount > 1) {
+ // We have enough space. Lets add some margin too.
+ int margin = (lp.width - totalItemWidth) / (visibleChildCount-1);
+ View lastChild = null;
+
+ // Set margin of all visible children except the last visible child
+ for (int i = 0; i < visibleChildCount; i++) {
+ if (lastChild != null) {
+ MarginLayoutParams clp = (MarginLayoutParams) lastChild.getLayoutParams();
+ if (isLayoutRtl) {
+ clp.leftMargin = margin;
+ } else {
+ clp.rightMargin = margin;
+ }
+ lastChild.setLayoutParams(clp);
+ lastChild = null;
+ }
+ View thisChild = overviewMode.getChildAt(i);
+ if (thisChild.getVisibility() != View.GONE) {
+ lastChild = thisChild;
+ }
+ }
+ }
}
}
}
diff --git a/src/com/android/launcher3/DragController.java b/src/com/android/launcher3/DragController.java
index 6d0a2be63..480dce999 100644
--- a/src/com/android/launcher3/DragController.java
+++ b/src/com/android/launcher3/DragController.java
@@ -26,10 +26,16 @@ import android.graphics.Rect;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;
-import android.view.*;
+import android.view.HapticFeedbackConstants;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.view.VelocityTracker;
+import android.view.View;
+import android.view.ViewConfiguration;
import android.view.inputmethod.InputMethodManager;
import java.util.ArrayList;
+import java.util.HashSet;
/**
* Class for initiating a drag within a view or across multiple views.
@@ -318,18 +324,17 @@ public class DragController {
}
endDrag();
}
- public void onAppsRemoved(final ArrayList<String> packageNames, ArrayList<AppInfo> appInfos) {
+ public void onAppsRemoved(final ArrayList<String> packageNames, HashSet<ComponentName> cns) {
// Cancel the current drag if we are removing an app that we are dragging
if (mDragObject != null) {
Object rawDragInfo = mDragObject.dragInfo;
if (rawDragInfo instanceof ShortcutInfo) {
ShortcutInfo dragInfo = (ShortcutInfo) rawDragInfo;
- for (AppInfo info : appInfos) {
+ for (ComponentName componentName : cns) {
// Added null checks to prevent NPE we've seen in the wild
- if (dragInfo != null &&
- dragInfo.intent != null && info != null) {
+ if (dragInfo != null && dragInfo.intent != null) {
ComponentName cn = dragInfo.intent.getComponent();
- boolean isSameComponent = cn != null && (cn.equals(info.componentName) ||
+ boolean isSameComponent = cn != null && (cn.equals(componentName) ||
packageNames.contains(cn.getPackageName()));
if (isSameComponent) {
cancelDrag();
diff --git a/src/com/android/launcher3/DragLayer.java b/src/com/android/launcher3/DragLayer.java
index a8a61ea89..a352b7914 100644
--- a/src/com/android/launcher3/DragLayer.java
+++ b/src/com/android/launcher3/DragLayer.java
@@ -38,12 +38,14 @@ import android.view.animation.Interpolator;
import android.widget.FrameLayout;
import android.widget.TextView;
+import com.android.launcher3.InsettableFrameLayout.LayoutParams;
+
import java.util.ArrayList;
/**
* A ViewGroup that coordinates dragging across its descendants
*/
-public class DragLayer extends FrameLayout implements ViewGroup.OnHierarchyChangeListener {
+public class DragLayer extends InsettableFrameLayout {
private DragController mDragController;
private int[] mTmpXY = new int[2];
@@ -71,8 +73,6 @@ public class DragLayer extends FrameLayout implements ViewGroup.OnHierarchyChang
private TouchCompleteListener mTouchCompleteListener;
- private final Rect mInsets = new Rect();
-
private View mOverlayView;
private int mTopViewIndex;
private int mChildCountOnLastUpdate = -1;
@@ -89,6 +89,8 @@ public class DragLayer extends FrameLayout implements ViewGroup.OnHierarchyChang
private Drawable mLeftHoverDrawableActive;
private Drawable mRightHoverDrawableActive;
+ private boolean mBlockTouches = false;
+
/**
* Used to create a new DragLayer from XML.
*
@@ -101,7 +103,6 @@ public class DragLayer extends FrameLayout implements ViewGroup.OnHierarchyChang
// Disable multitouch across the workspace/all apps/customize tray
setMotionEventSplittingEnabled(false);
setChildrenDrawingOrderEnabled(true);
- setOnHierarchyChangeListener(this);
final Resources res = getResources();
mLeftHoverDrawable = res.getDrawable(R.drawable.page_hover_left);
@@ -121,27 +122,6 @@ public class DragLayer extends FrameLayout implements ViewGroup.OnHierarchyChang
return mDragController.dispatchKeyEvent(event) || super.dispatchKeyEvent(event);
}
- @Override
- protected boolean fitSystemWindows(Rect insets) {
- final int n = getChildCount();
- for (int i = 0; i < n; i++) {
- final View child = getChildAt(i);
- setInsets(child, insets, mInsets);
- }
- mInsets.set(insets);
- return true; // I'll take it from here
- }
-
- Rect getInsets() {
- return mInsets;
- }
-
- @Override
- public void addView(View child, int index, android.view.ViewGroup.LayoutParams params) {
- super.addView(child, index, params);
- setInsets(child, mInsets, new Rect());
- }
-
public void showOverlayView(View overlayView) {
LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
mOverlayView = overlayView;
@@ -156,19 +136,6 @@ public class DragLayer extends FrameLayout implements ViewGroup.OnHierarchyChang
removeView(mOverlayView);
}
- private void setInsets(View child, Rect newInsets, Rect oldInsets) {
- final FrameLayout.LayoutParams flp = (FrameLayout.LayoutParams) child.getLayoutParams();
- if (child instanceof Insettable) {
- ((Insettable) child).setInsets(newInsets);
- } else {
- flp.topMargin += (newInsets.top - oldInsets.top);
- flp.leftMargin += (newInsets.left - oldInsets.left);
- flp.rightMargin += (newInsets.right - oldInsets.right);
- flp.bottomMargin += (newInsets.bottom - oldInsets.bottom);
- }
- child.setLayoutParams(flp);
- }
-
private boolean isEventOverFolderTextRegion(Folder folder, MotionEvent ev) {
getDescendantRectRelativeToSelf(folder.getEditTextRegion(), mHitRect);
if (mHitRect.contains((int) ev.getX(), (int) ev.getY())) {
@@ -185,11 +152,19 @@ public class DragLayer extends FrameLayout implements ViewGroup.OnHierarchyChang
return false;
}
+ public void setBlockTouch(boolean block) {
+ mBlockTouches = block;
+ }
+
private boolean handleTouchDown(MotionEvent ev, boolean intercept) {
Rect hitRect = new Rect();
int x = (int) ev.getX();
int y = (int) ev.getY();
+ if (mBlockTouches) {
+ return true;
+ }
+
for (AppWidgetResizeFrame child: mResizeFrames) {
child.getHitRect(hitRect);
if (hitRect.contains(x, y)) {
@@ -332,6 +307,10 @@ public class DragLayer extends FrameLayout implements ViewGroup.OnHierarchyChang
int x = (int) ev.getX();
int y = (int) ev.getY();
+ if (mBlockTouches) {
+ return true;
+ }
+
if (action == MotionEvent.ACTION_DOWN) {
if (handleTouchDown(ev, false)) {
return true;
@@ -433,17 +412,43 @@ public class DragLayer extends FrameLayout implements ViewGroup.OnHierarchyChang
return mDragController.dispatchUnhandledMove(focused, direction);
}
- public static class LayoutParams extends FrameLayout.LayoutParams {
+ @Override
+ public LayoutParams generateLayoutParams(AttributeSet attrs) {
+ return new LayoutParams(getContext(), attrs);
+ }
+
+ @Override
+ protected LayoutParams generateDefaultLayoutParams() {
+ return new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
+ }
+
+ // Override to allow type-checking of LayoutParams.
+ @Override
+ protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
+ return p instanceof LayoutParams;
+ }
+
+ @Override
+ protected LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
+ return new LayoutParams(p);
+ }
+
+ public static class LayoutParams extends InsettableFrameLayout.LayoutParams {
public int x, y;
public boolean customPosition = false;
- /**
- * {@inheritDoc}
- */
+ public LayoutParams(Context c, AttributeSet attrs) {
+ super(c, attrs);
+ }
+
public LayoutParams(int width, int height) {
super(width, height);
}
+ public LayoutParams(ViewGroup.LayoutParams lp) {
+ super(lp);
+ }
+
public void setWidth(int width) {
this.width = width;
}
@@ -801,6 +806,7 @@ public class DragLayer extends FrameLayout implements ViewGroup.OnHierarchyChang
@Override
public void onChildViewAdded(View parent, View child) {
+ super.onChildViewAdded(parent, child);
if (mOverlayView != null) {
// ensure that the overlay view stays on top. we can't use drawing order for this
// because in API level 16 touch dispatch doesn't respect drawing order.
diff --git a/src/com/android/launcher3/DrawableStateProxyView.java b/src/com/android/launcher3/DrawableStateProxyView.java
deleted file mode 100644
index c83659ad5..000000000
--- a/src/com/android/launcher3/DrawableStateProxyView.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2012 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.launcher3;
-
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.util.AttributeSet;
-import android.view.MotionEvent;
-import android.view.View;
-import android.widget.LinearLayout;
-
-public class DrawableStateProxyView extends LinearLayout {
-
- private View mView;
- private int mViewId;
-
- public DrawableStateProxyView(Context context) {
- this(context, null);
- }
-
- public DrawableStateProxyView(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
-
- public DrawableStateProxyView(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
-
- TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.DrawableStateProxyView,
- defStyle, 0);
- mViewId = a.getResourceId(R.styleable.DrawableStateProxyView_sourceViewId, -1);
- a.recycle();
-
- setFocusable(false);
- }
-
- @Override
- protected void drawableStateChanged() {
- super.drawableStateChanged();
-
- if (mView == null) {
- View parent = (View) getParent();
- mView = parent.findViewById(mViewId);
- }
- if (mView != null) {
- mView.setPressed(isPressed());
- mView.setHovered(isHovered());
- }
- }
-
- @Override
- public boolean onHoverEvent(MotionEvent event) {
- return false;
- }
-}
diff --git a/src/com/android/launcher3/DynamicGrid.java b/src/com/android/launcher3/DynamicGrid.java
index 94a07d706..aa08148d2 100644
--- a/src/com/android/launcher3/DynamicGrid.java
+++ b/src/com/android/launcher3/DynamicGrid.java
@@ -60,41 +60,30 @@ public class DynamicGrid {
DEFAULT_ICON_SIZE_PX = pxFromDp(DEFAULT_ICON_SIZE_DP, dm);
// Our phone profiles include the bar sizes in each orientation
deviceProfiles.add(new DeviceProfile("Super Short Stubby",
- 255, 300, 2, 3, 48, 13, (hasAA ? 3 : 5), 48, R.xml.default_workspace_4x4,
- R.xml.default_workspace_4x4_no_all_apps));
+ 255, 300, 2, 3, 48, 13, (hasAA ? 3 : 5), 48, R.xml.default_workspace_4x4));
deviceProfiles.add(new DeviceProfile("Shorter Stubby",
- 255, 400, 3, 3, 48, 13, (hasAA ? 3 : 5), 48, R.xml.default_workspace_4x4,
- R.xml.default_workspace_4x4_no_all_apps));
+ 255, 400, 3, 3, 48, 13, (hasAA ? 3 : 5), 48, R.xml.default_workspace_4x4));
deviceProfiles.add(new DeviceProfile("Short Stubby",
- 275, 420, 3, 4, 48, 13, (hasAA ? 5 : 5), 48, R.xml.default_workspace_4x4,
- R.xml.default_workspace_4x4_no_all_apps));
+ 275, 420, 3, 4, 48, 13, (hasAA ? 5 : 5), 48, R.xml.default_workspace_4x4));
deviceProfiles.add(new DeviceProfile("Stubby",
- 255, 450, 3, 4, 48, 13, (hasAA ? 5 : 5), 48, R.xml.default_workspace_4x4,
- R.xml.default_workspace_4x4_no_all_apps));
+ 255, 450, 3, 4, 48, 13, (hasAA ? 5 : 5), 48, R.xml.default_workspace_4x4));
deviceProfiles.add(new DeviceProfile("Nexus S",
- 296, 491.33f, 4, 4, 48, 13, (hasAA ? 5 : 5), 48, R.xml.default_workspace_4x4,
- R.xml.default_workspace_4x4_no_all_apps));
+ 296, 491.33f, 4, 4, 48, 13, (hasAA ? 5 : 5), 48, R.xml.default_workspace_4x4));
deviceProfiles.add(new DeviceProfile("Nexus 4",
- 335, 567, 4, 4, DEFAULT_ICON_SIZE_DP, 13, (hasAA ? 5 : 5), 56, R.xml.default_workspace_4x4,
- R.xml.default_workspace_4x4_no_all_apps));
+ 335, 567, 4, 4, DEFAULT_ICON_SIZE_DP, 13, (hasAA ? 5 : 5), 56, R.xml.default_workspace_4x4));
deviceProfiles.add(new DeviceProfile("Nexus 5",
- 359, 567, 4, 4, DEFAULT_ICON_SIZE_DP, 13, (hasAA ? 5 : 5), 56, R.xml.default_workspace_4x4,
- R.xml.default_workspace_4x4_no_all_apps));
+ 359, 567, 4, 4, DEFAULT_ICON_SIZE_DP, 13, (hasAA ? 5 : 5), 56, R.xml.default_workspace_4x4));
deviceProfiles.add(new DeviceProfile("Large Phone",
- 406, 694, 5, 5, 64, 14.4f, 5, 56, R.xml.default_workspace_5x5,
- R.xml.default_workspace_5x5_no_all_apps));
+ 406, 694, 5, 5, 64, 14.4f, 5, 56, R.xml.default_workspace_5x5));
// The tablet profile is odd in that the landscape orientation
// also includes the nav bar on the side
deviceProfiles.add(new DeviceProfile("Nexus 7",
- 575, 904, 5, 6, 72, 14.4f, 7, 60, R.xml.default_workspace_5x6,
- R.xml.default_workspace_5x6_no_all_apps));
+ 575, 904, 5, 6, 72, 14.4f, 7, 60, R.xml.default_workspace_5x6));
// Larger tablet profiles always have system bars on the top & bottom
deviceProfiles.add(new DeviceProfile("Nexus 10",
- 727, 1207, 5, 6, 76, 14.4f, 7, 64, R.xml.default_workspace_5x6,
- R.xml.default_workspace_5x6_no_all_apps));
+ 727, 1207, 5, 6, 76, 14.4f, 7, 64, R.xml.default_workspace_5x6));
deviceProfiles.add(new DeviceProfile("20-inch Tablet",
- 1527, 2527, 7, 7, 100, 20, 7, 72, R.xml.default_workspace_4x4,
- R.xml.default_workspace_4x4_no_all_apps));
+ 1527, 2527, 7, 7, 100, 20, 7, 72, R.xml.default_workspace_4x4));
mMinWidth = dpiFromPx(minWidthPx, dm);
mMinHeight = dpiFromPx(minHeightPx, dm);
mProfile = new DeviceProfile(context, deviceProfiles,
diff --git a/src/com/android/launcher3/FirstFrameAnimatorHelper.java b/src/com/android/launcher3/FirstFrameAnimatorHelper.java
index f4c49d77a..095c5631d 100644
--- a/src/com/android/launcher3/FirstFrameAnimatorHelper.java
+++ b/src/com/android/launcher3/FirstFrameAnimatorHelper.java
@@ -92,12 +92,14 @@ public class FirstFrameAnimatorHelper extends AnimatorListenerAdapter
}
final long currentPlayTime = animation.getCurrentPlayTime();
+ boolean isFinalFrame = Float.compare(1f, animation.getAnimatedFraction()) == 0;
+
if (!mHandlingOnAnimationUpdate &&
sVisible &&
- // If the current play time exceeds the duration, the animation
- // will get finished, even if we call setCurrentPlayTime -- therefore
+ // If the current play time exceeds the duration, or the animated fraction is 1,
+ // the animation will get finished, even if we call setCurrentPlayTime -- therefore
// don't adjust the animation in that case
- currentPlayTime < animation.getDuration()) {
+ currentPlayTime < animation.getDuration() && !isFinalFrame) {
mHandlingOnAnimationUpdate = true;
long frameNum = sGlobalFrameCounter - mStartFrame;
// If we haven't drawn our first frame, reset the time to t = 0
diff --git a/src/com/android/launcher3/FocusHelper.java b/src/com/android/launcher3/FocusHelper.java
index d529b3901..e60704718 100644
--- a/src/com/android/launcher3/FocusHelper.java
+++ b/src/com/android/launcher3/FocusHelper.java
@@ -17,12 +17,10 @@
package com.android.launcher3;
import android.content.res.Configuration;
-import android.util.Log;
import android.view.KeyEvent;
import android.view.SoundEffectConstants;
import android.view.View;
import android.view.ViewGroup;
-import android.view.ViewParent;
import android.widget.ScrollView;
import java.util.ArrayList;
@@ -58,16 +56,6 @@ class HotseatIconKeyEventListener implements View.OnKeyListener {
}
public class FocusHelper {
- /**
- * Private helper to get the parent TabHost in the view hiearchy.
- */
- private static AppsCustomizeTabHost findTabHostParent(View v) {
- ViewParent p = v.getParent();
- while (p != null && !(p instanceof AppsCustomizeTabHost)) {
- p = p.getParent();
- }
- return (AppsCustomizeTabHost) p;
- }
/**
* Returns the Viewgroup containing page contents for the page at the index specified.
@@ -82,148 +70,6 @@ public class FocusHelper {
}
/**
- * Handles key events in a PageViewExtendedLayout containing PagedViewWidgets.
- */
- static boolean handlePagedViewGridLayoutWidgetKeyEvent(PagedViewWidget w, int keyCode,
- KeyEvent e) {
-
- final PagedViewGridLayout parent = (PagedViewGridLayout) w.getParent();
- final PagedView container = (PagedView) parent.getParent();
- final int widgetIndex = parent.indexOfChild(w);
- final int widgetCount = parent.getChildCount();
- final int pageIndex = ((PagedView) container).indexToPage(container.indexOfChild(parent));
- final int pageCount = container.getChildCount();
- final int cellCountX = parent.getCellCountX();
- final int cellCountY = parent.getCellCountY();
- final int x = widgetIndex % cellCountX;
- final int y = widgetIndex / cellCountX;
-
- final int action = e.getAction();
- final boolean handleKeyEvent = (action != KeyEvent.ACTION_UP);
- ViewGroup newParent = null;
- // Now that we load items in the bg asynchronously, we can't just focus
- // child siblings willy-nilly
- View child = null;
- boolean wasHandled = false;
- switch (keyCode) {
- case KeyEvent.KEYCODE_DPAD_LEFT:
- if (handleKeyEvent) {
- // Select the previous widget or the last widget on the previous page
- if (widgetIndex > 0) {
- parent.getChildAt(widgetIndex - 1).requestFocus();
- } else {
- if (pageIndex > 0) {
- newParent = getAppsCustomizePage(container, pageIndex - 1);
- if (newParent != null) {
- child = newParent.getChildAt(newParent.getChildCount() - 1);
- if (child != null) child.requestFocus();
- }
- }
- }
- }
- wasHandled = true;
- break;
- case KeyEvent.KEYCODE_DPAD_RIGHT:
- if (handleKeyEvent) {
- // Select the next widget or the first widget on the next page
- if (widgetIndex < (widgetCount - 1)) {
- parent.getChildAt(widgetIndex + 1).requestFocus();
- } else {
- if (pageIndex < (pageCount - 1)) {
- newParent = getAppsCustomizePage(container, pageIndex + 1);
- if (newParent != null) {
- child = newParent.getChildAt(0);
- if (child != null) child.requestFocus();
- }
- }
- }
- }
- wasHandled = true;
- break;
- case KeyEvent.KEYCODE_DPAD_UP:
- if (handleKeyEvent) {
- // Select the closest icon in the previous row, otherwise select the tab bar
- if (y > 0) {
- int newWidgetIndex = ((y - 1) * cellCountX) + x;
- child = parent.getChildAt(newWidgetIndex);
- if (child != null) child.requestFocus();
- }
- }
- wasHandled = true;
- break;
- case KeyEvent.KEYCODE_DPAD_DOWN:
- if (handleKeyEvent) {
- // Select the closest icon in the previous row, otherwise do nothing
- if (y < (cellCountY - 1)) {
- int newWidgetIndex = Math.min(widgetCount - 1, ((y + 1) * cellCountX) + x);
- child = parent.getChildAt(newWidgetIndex);
- if (child != null) child.requestFocus();
- }
- }
- wasHandled = true;
- break;
- case KeyEvent.KEYCODE_ENTER:
- case KeyEvent.KEYCODE_DPAD_CENTER:
- if (handleKeyEvent) {
- // Simulate a click on the widget
- View.OnClickListener clickListener = (View.OnClickListener) container;
- clickListener.onClick(w);
- }
- wasHandled = true;
- break;
- case KeyEvent.KEYCODE_PAGE_UP:
- if (handleKeyEvent) {
- // Select the first item on the previous page, or the first item on this page
- // if there is no previous page
- if (pageIndex > 0) {
- newParent = getAppsCustomizePage(container, pageIndex - 1);
- if (newParent != null) {
- child = newParent.getChildAt(0);
- }
- } else {
- child = parent.getChildAt(0);
- }
- if (child != null) child.requestFocus();
- }
- wasHandled = true;
- break;
- case KeyEvent.KEYCODE_PAGE_DOWN:
- if (handleKeyEvent) {
- // Select the first item on the next page, or the last item on this page
- // if there is no next page
- if (pageIndex < (pageCount - 1)) {
- newParent = getAppsCustomizePage(container, pageIndex + 1);
- if (newParent != null) {
- child = newParent.getChildAt(0);
- }
- } else {
- child = parent.getChildAt(widgetCount - 1);
- }
- if (child != null) child.requestFocus();
- }
- wasHandled = true;
- break;
- case KeyEvent.KEYCODE_MOVE_HOME:
- if (handleKeyEvent) {
- // Select the first item on this page
- child = parent.getChildAt(0);
- if (child != null) child.requestFocus();
- }
- wasHandled = true;
- break;
- case KeyEvent.KEYCODE_MOVE_END:
- if (handleKeyEvent) {
- // Select the last item on this page
- parent.getChildAt(widgetCount - 1).requestFocus();
- }
- wasHandled = true;
- break;
- default: break;
- }
- return wasHandled;
- }
-
- /**
* Handles key events in a PageViewCellLayout containing PagedViewIcons.
*/
static boolean handleAppsCustomizeKeyEvent(View v, int keyCode, KeyEvent e) {
@@ -394,60 +240,6 @@ public class FocusHelper {
}
/**
- * Handles key events in the tab widget.
- */
- static boolean handleTabKeyEvent(AccessibleTabView v, int keyCode, KeyEvent e) {
- if (!LauncherAppState.getInstance().isScreenLarge()) return false;
-
- final FocusOnlyTabWidget parent = (FocusOnlyTabWidget) v.getParent();
- final AppsCustomizeTabHost tabHost = findTabHostParent(parent);
- final ViewGroup contents = tabHost.getContent();
- final int tabCount = parent.getTabCount();
- final int tabIndex = parent.getChildTabIndex(v);
-
- final int action = e.getAction();
- final boolean handleKeyEvent = (action != KeyEvent.ACTION_UP);
- boolean wasHandled = false;
- switch (keyCode) {
- case KeyEvent.KEYCODE_DPAD_LEFT:
- if (handleKeyEvent) {
- // Select the previous tab
- if (tabIndex > 0) {
- parent.getChildTabViewAt(tabIndex - 1).requestFocus();
- }
- }
- wasHandled = true;
- break;
- case KeyEvent.KEYCODE_DPAD_RIGHT:
- if (handleKeyEvent) {
- // Select the next tab, or if the last tab has a focus right id, select that
- if (tabIndex < (tabCount - 1)) {
- parent.getChildTabViewAt(tabIndex + 1).requestFocus();
- } else {
- if (v.getNextFocusRightId() != View.NO_ID) {
- tabHost.findViewById(v.getNextFocusRightId()).requestFocus();
- }
- }
- }
- wasHandled = true;
- break;
- case KeyEvent.KEYCODE_DPAD_UP:
- // Do nothing
- wasHandled = true;
- break;
- case KeyEvent.KEYCODE_DPAD_DOWN:
- if (handleKeyEvent) {
- // Select the content view
- contents.requestFocus();
- }
- wasHandled = true;
- break;
- default: break;
- }
- return wasHandled;
- }
-
- /**
* Handles key events in the workspace hotseat (bottom of the screen).
*/
static boolean handleHotseatButtonKeyEvent(View v, int keyCode, KeyEvent e, int orientation) {
diff --git a/src/com/android/launcher3/FocusIndicatorView.java b/src/com/android/launcher3/FocusIndicatorView.java
index 12b7a4076..7d4664abb 100644
--- a/src/com/android/launcher3/FocusIndicatorView.java
+++ b/src/com/android/launcher3/FocusIndicatorView.java
@@ -16,6 +16,8 @@
package com.android.launcher3;
+import android.animation.ObjectAnimator;
+import android.animation.PropertyValuesHolder;
import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
@@ -28,6 +30,7 @@ public class FocusIndicatorView extends View implements View.OnFocusChangeListen
// It can be any number >0. The view is resized using scaleX and scaleY.
static final int DEFAULT_LAYOUT_SIZE = 100;
private static final float MIN_VISIBLE_ALPHA = 0.2f;
+ private static final long ANIM_DURATION = 150;
private static final int[] sTempPos = new int[2];
private static final int[] sTempShift = new int[2];
@@ -35,6 +38,9 @@ public class FocusIndicatorView extends View implements View.OnFocusChangeListen
private final int[] mIndicatorPos = new int[2];
private final int[] mTargetViewPos = new int[2];
+ private ObjectAnimator mCurrentAnimation;
+ private ViewAnimState mTargetState;
+
private View mLastFocusedView;
private boolean mInitiated;
@@ -82,34 +88,58 @@ public class FocusIndicatorView extends View implements View.OnFocusChangeListen
int indicatorWidth = getWidth();
int indicatorHeight = getHeight();
- float scaleX = v.getScaleX() * v.getWidth() / indicatorWidth;
- float scaleY = v.getScaleY() * v.getHeight() / indicatorHeight;
+ endCurrentAnimation();
+ ViewAnimState nextState = new ViewAnimState();
+ nextState.scaleX = v.getScaleX() * v.getWidth() / indicatorWidth;
+ nextState.scaleY = v.getScaleY() * v.getHeight() / indicatorHeight;
getLocationRelativeToParentPagedView(v, mTargetViewPos);
- float x = mTargetViewPos[0] - mIndicatorPos[0] - (1 - scaleX) * indicatorWidth / 2;
- float y = mTargetViewPos[1] - mIndicatorPos[1] - (1 - scaleY) * indicatorHeight / 2;
+ nextState.x = mTargetViewPos[0] - mIndicatorPos[0] - (1 - nextState.scaleX) * indicatorWidth / 2;
+ nextState.y = mTargetViewPos[1] - mIndicatorPos[1] - (1 - nextState.scaleY) * indicatorHeight / 2;
if (getAlpha() > MIN_VISIBLE_ALPHA) {
- animate()
- .translationX(x)
- .translationY(y)
- .scaleX(scaleX)
- .scaleY(scaleY)
- .alpha(1);
+ mTargetState = nextState;
+ mCurrentAnimation = LauncherAnimUtils.ofPropertyValuesHolder(this,
+ PropertyValuesHolder.ofFloat(View.ALPHA, 1),
+ PropertyValuesHolder.ofFloat(View.TRANSLATION_X, mTargetState.x),
+ PropertyValuesHolder.ofFloat(View.TRANSLATION_Y, mTargetState.y),
+ PropertyValuesHolder.ofFloat(View.SCALE_X, mTargetState.scaleX),
+ PropertyValuesHolder.ofFloat(View.SCALE_Y, mTargetState.scaleY));
} else {
- setTranslationX(x);
- setTranslationY(y);
- setScaleX(scaleX);
- setScaleY(scaleY);
- animate().alpha(1);
+ applyState(nextState);
+ mCurrentAnimation = LauncherAnimUtils.ofPropertyValuesHolder(this,
+ PropertyValuesHolder.ofFloat(View.ALPHA, 1));
}
mLastFocusedView = v;
} else {
if (mLastFocusedView == v) {
mLastFocusedView = null;
- animate().alpha(0);
+ endCurrentAnimation();
+ mCurrentAnimation = LauncherAnimUtils.ofPropertyValuesHolder(this,
+ PropertyValuesHolder.ofFloat(View.ALPHA, 0));
}
}
+ if (mCurrentAnimation != null) {
+ mCurrentAnimation.setDuration(ANIM_DURATION).start();
+ }
+ }
+
+ private void endCurrentAnimation() {
+ if (mCurrentAnimation != null) {
+ mCurrentAnimation.cancel();
+ mCurrentAnimation = null;
+ }
+ if (mTargetState != null) {
+ applyState(mTargetState);
+ mTargetState = null;
+ }
+ }
+
+ private void applyState(ViewAnimState state) {
+ setTranslationX(state.x);
+ setTranslationY(state.y);
+ setScaleX(state.scaleX);
+ setScaleY(state.scaleY);
}
@Override
@@ -143,4 +173,8 @@ public class FocusIndicatorView extends View implements View.OnFocusChangeListen
shift[0] = shift[1] = 0;
}
}
+
+ private static final class ViewAnimState {
+ float x, y, scaleX, scaleY;
+ }
}
diff --git a/src/com/android/launcher3/HolographicImageView.java b/src/com/android/launcher3/HolographicImageView.java
deleted file mode 100644
index 18ac092e6..000000000
--- a/src/com/android/launcher3/HolographicImageView.java
+++ /dev/null
@@ -1,121 +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.launcher3;
-
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.graphics.Canvas;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.StateListDrawable;
-import android.util.AttributeSet;
-import android.view.MotionEvent;
-import android.view.View;
-import android.widget.ImageView;
-
-public class HolographicImageView extends ImageView {
-
- private final HolographicViewHelper mHolographicHelper;
- private boolean mHotwordOn;
- private boolean mIsPressed;
- private boolean mIsFocused;
-
- public HolographicImageView(Context context) {
- this(context, null);
- }
-
- public HolographicImageView(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- public HolographicImageView(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
-
- mHolographicHelper = new HolographicViewHelper(context);
- TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.HolographicLinearLayout,
- defStyle, 0);
- mHotwordOn = a.getBoolean(R.styleable.HolographicLinearLayout_stateHotwordOn, false);
- a.recycle();
-
- setOnTouchListener(new OnTouchListener() {
- @Override
- public boolean onTouch(View v, MotionEvent event) {
- if (isPressed() != mIsPressed) {
- mIsPressed = isPressed();
- refreshDrawableState();
- }
- return false;
- }
- });
-
- setOnFocusChangeListener(new OnFocusChangeListener() {
- @Override
- public void onFocusChange(View v, boolean hasFocus) {
- if (isFocused() != mIsFocused) {
- mIsFocused = isFocused();
- refreshDrawableState();
- }
- }
- });
- }
-
- void invalidatePressedFocusedStates() {
- mHolographicHelper.invalidatePressedFocusedStates(this);
- }
-
- @Override
- protected void drawableStateChanged() {
- super.drawableStateChanged();
-
- mHolographicHelper.generatePressedFocusedStates(this);
- Drawable d = getDrawable();
- if (d instanceof StateListDrawable) {
- StateListDrawable sld = (StateListDrawable) d;
- sld.setState(getDrawableState());
- sld.invalidateSelf();
- }
- }
-
- @Override
- protected void onDraw(Canvas canvas) {
- super.onDraw(canvas);
-
- // One time call to generate the pressed/focused state -- must be called after
- // measure/layout
- mHolographicHelper.generatePressedFocusedStates(this);
- }
-
- private boolean isHotwordOn() {
- return mHotwordOn;
- }
-
- public void setHotwordState(boolean on) {
- if (on == mHotwordOn) {
- return;
- }
- mHotwordOn = on;
- refreshDrawableState();
- }
-
- @Override
- public int[] onCreateDrawableState(int extraSpace) {
- final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
- if (isHotwordOn()) {
- mergeDrawableStates(drawableState, new int[] {R.attr.stateHotwordOn});
- }
- return drawableState;
- }
-}
diff --git a/src/com/android/launcher3/HolographicLinearLayout.java b/src/com/android/launcher3/HolographicLinearLayout.java
deleted file mode 100644
index 5344a7ee9..000000000
--- a/src/com/android/launcher3/HolographicLinearLayout.java
+++ /dev/null
@@ -1,134 +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.launcher3;
-
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.graphics.Canvas;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.StateListDrawable;
-import android.util.AttributeSet;
-import android.view.MotionEvent;
-import android.view.View;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-
-public class HolographicLinearLayout extends LinearLayout {
- private final HolographicViewHelper mHolographicHelper;
- private ImageView mImageView;
- private int mImageViewId;
-
- private boolean mHotwordOn;
- private boolean mIsPressed;
- private boolean mIsFocused;
-
- public HolographicLinearLayout(Context context) {
- this(context, null);
- }
-
- public HolographicLinearLayout(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- public HolographicLinearLayout(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
-
- TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.HolographicLinearLayout,
- defStyle, 0);
- mImageViewId = a.getResourceId(R.styleable.HolographicLinearLayout_sourceImageViewId, -1);
- mHotwordOn = a.getBoolean(R.styleable.HolographicLinearLayout_stateHotwordOn, false);
- a.recycle();
-
-
- setWillNotDraw(false);
- mHolographicHelper = new HolographicViewHelper(context);
-
- setOnTouchListener(new OnTouchListener() {
- @Override
- public boolean onTouch(View v, MotionEvent event) {
- if (isPressed() != mIsPressed) {
- mIsPressed = isPressed();
- refreshDrawableState();
- }
- return false;
- }
- });
-
- setOnFocusChangeListener(new OnFocusChangeListener() {
- @Override
- public void onFocusChange(View v, boolean hasFocus) {
- if (isFocused() != mIsFocused) {
- mIsFocused = isFocused();
- refreshDrawableState();
- }
- }
- });
- }
-
- @Override
- protected void drawableStateChanged() {
- super.drawableStateChanged();
-
- if (mImageView != null) {
- mHolographicHelper.generatePressedFocusedStates(mImageView);
- Drawable d = mImageView.getDrawable();
- if (d instanceof StateListDrawable) {
- StateListDrawable sld = (StateListDrawable) d;
- sld.setState(getDrawableState());
- sld.invalidateSelf();
- }
- }
- }
-
- void invalidatePressedFocusedStates() {
- mHolographicHelper.invalidatePressedFocusedStates(mImageView);
- invalidate();
- }
-
- @Override
- protected void onDraw(Canvas canvas) {
- super.onDraw(canvas);
-
- // One time call to generate the pressed/focused state -- must be called after
- // measure/layout
- if (mImageView == null) {
- mImageView = (ImageView) findViewById(mImageViewId);
- }
- mHolographicHelper.generatePressedFocusedStates(mImageView);
- }
-
- private boolean isHotwordOn() {
- return mHotwordOn;
- }
-
- public void setHotwordState(boolean on) {
- if (on == mHotwordOn) {
- return;
- }
- mHotwordOn = on;
- refreshDrawableState();
- }
-
- @Override
- public int[] onCreateDrawableState(int extraSpace) {
- final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
- if (isHotwordOn()) {
- mergeDrawableStates(drawableState, new int[] {R.attr.stateHotwordOn});
- }
- return drawableState;
- }
-}
diff --git a/src/com/android/launcher3/HolographicViewHelper.java b/src/com/android/launcher3/HolographicViewHelper.java
deleted file mode 100644
index 7ef035555..000000000
--- a/src/com/android/launcher3/HolographicViewHelper.java
+++ /dev/null
@@ -1,109 +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.launcher3;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.PorterDuff;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.StateListDrawable;
-import android.widget.ImageView;
-
-public class HolographicViewHelper {
-
- private final Canvas mTempCanvas = new Canvas();
-
- private boolean mStatesUpdated;
- private int mHighlightColor, mHotwordColor;
-
- public HolographicViewHelper(Context context) {
- Resources res = context.getResources();
- mHighlightColor = res.getColor(android.R.color.holo_blue_light);
- mHotwordColor = res.getColor(android.R.color.holo_green_light);
- }
-
- /**
- * Generate the pressed/focused states if necessary.
- */
- void generatePressedFocusedStates(ImageView v) {
- if (!mStatesUpdated && v != null) {
- mStatesUpdated = true;
- Bitmap original = createOriginalImage(v, mTempCanvas);
- Bitmap outline = createImageWithOverlay(v, mTempCanvas, mHighlightColor);
- Bitmap hotword = createImageWithOverlay(v, mTempCanvas, mHotwordColor);
- FastBitmapDrawable originalD = new FastBitmapDrawable(original);
- FastBitmapDrawable outlineD = new FastBitmapDrawable(outline);
- FastBitmapDrawable hotwordD = new FastBitmapDrawable(hotword);
-
- StateListDrawable states = new StateListDrawable();
-
- states.addState(new int[] {android.R.attr.state_pressed}, outlineD);
- states.addState(new int[] {android.R.attr.state_focused}, outlineD);
- states.addState(new int[] {R.attr.stateHotwordOn}, hotwordD);
- states.addState(new int[] {}, originalD);
- v.setImageDrawable(states);
- }
- }
-
- /**
- * Invalidates the pressed/focused states.
- */
- void invalidatePressedFocusedStates(ImageView v) {
- mStatesUpdated = false;
- if (v != null) {
- v.invalidate();
- }
- }
-
- /**
- * Creates a copy of the original image.
- */
- private Bitmap createOriginalImage(ImageView v, Canvas canvas) {
- final Drawable d = v.getDrawable();
- final Bitmap b = Bitmap.createBitmap(
- d.getIntrinsicWidth(), d.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
-
- canvas.setBitmap(b);
- canvas.save();
- d.draw(canvas);
- canvas.restore();
- canvas.setBitmap(null);
-
- return b;
- }
-
- /**
- * Creates a new press state image which is the old image with a blue overlay.
- * Responsibility for the bitmap is transferred to the caller.
- */
- private Bitmap createImageWithOverlay(ImageView v, Canvas canvas, int color) {
- final Drawable d = v.getDrawable();
- final Bitmap b = Bitmap.createBitmap(
- d.getIntrinsicWidth(), d.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
-
- canvas.setBitmap(b);
- canvas.save();
- d.draw(canvas);
- canvas.restore();
- canvas.drawColor(color, PorterDuff.Mode.SRC_IN);
- canvas.setBitmap(null);
-
- return b;
- }
-}
diff --git a/src/com/android/launcher3/IconCache.java b/src/com/android/launcher3/IconCache.java
index bb71d776c..5a0875b30 100644
--- a/src/com/android/launcher3/IconCache.java
+++ b/src/com/android/launcher3/IconCache.java
@@ -24,12 +24,10 @@ import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.pm.ResolveInfo;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
-import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import android.util.Log;
@@ -118,11 +116,10 @@ public class IconCache {
}
public Drawable getFullResDefaultActivityIcon() {
- return getFullResIcon(Resources.getSystem(),
- android.R.mipmap.sym_def_app_icon);
+ return getFullResIcon(Resources.getSystem(), android.R.mipmap.sym_def_app_icon);
}
- public Drawable getFullResIcon(Resources resources, int iconId) {
+ private Drawable getFullResIcon(Resources resources, int iconId) {
Drawable d;
try {
d = resources.getDrawableForDensity(iconId, mIconDpi);
@@ -152,12 +149,7 @@ public class IconCache {
return mIconDpi;
}
- public Drawable getFullResIcon(ResolveInfo info) {
- return getFullResIcon(info.activityInfo);
- }
-
public Drawable getFullResIcon(ActivityInfo info) {
-
Resources resources;
try {
resources = mPackageManager.getResourcesForApplication(
@@ -191,16 +183,14 @@ public class IconCache {
/**
* Remove any records for the supplied ComponentName.
*/
- public void remove(ComponentName componentName, UserHandleCompat user) {
- synchronized (mCache) {
- mCache.remove(new CacheKey(componentName, user));
- }
+ public synchronized void remove(ComponentName componentName, UserHandleCompat user) {
+ mCache.remove(new CacheKey(componentName, user));
}
/**
* Remove any records for the supplied package name.
*/
- public void remove(String packageName, UserHandleCompat user) {
+ public synchronized void remove(String packageName, UserHandleCompat user) {
HashSet<CacheKey> forDeletion = new HashSet<CacheKey>();
for (CacheKey key: mCache.keySet()) {
if (key.componentName.getPackageName().equals(packageName)
@@ -216,24 +206,20 @@ public class IconCache {
/**
* Empty out the cache.
*/
- public void flush() {
- synchronized (mCache) {
- mCache.clear();
- }
+ public synchronized void flush() {
+ mCache.clear();
}
/**
* Empty out the cache that aren't of the correct grid size
*/
- public void flushInvalidIcons(DeviceProfile grid) {
- synchronized (mCache) {
- Iterator<Entry<CacheKey, CacheEntry>> it = mCache.entrySet().iterator();
- while (it.hasNext()) {
- final CacheEntry e = it.next().getValue();
- if ((e.icon != null) && (e.icon.getWidth() < grid.iconSizePx
- || e.icon.getHeight() < grid.iconSizePx)) {
- it.remove();
- }
+ public synchronized void flushInvalidIcons(DeviceProfile grid) {
+ Iterator<Entry<CacheKey, CacheEntry>> it = mCache.entrySet().iterator();
+ while (it.hasNext()) {
+ final CacheEntry e = it.next().getValue();
+ if ((e.icon != null) && (e.icon.getWidth() < grid.iconSizePx
+ || e.icon.getHeight() < grid.iconSizePx)) {
+ it.remove();
}
}
}
@@ -241,90 +227,78 @@ public class IconCache {
/**
* Fill in "application" with the icon and label for "info."
*/
- public void getTitleAndIcon(AppInfo application, LauncherActivityInfoCompat info,
+ public synchronized void getTitleAndIcon(AppInfo application, LauncherActivityInfoCompat info,
HashMap<Object, CharSequence> labelCache) {
- synchronized (mCache) {
- CacheEntry entry = cacheLocked(application.componentName, info, labelCache,
- info.getUser(), false);
-
- application.title = entry.title;
- application.iconBitmap = entry.icon;
- application.contentDescription = entry.contentDescription;
- }
- }
+ CacheEntry entry = cacheLocked(application.componentName, info, labelCache,
+ info.getUser(), false);
- public Bitmap getIcon(Intent intent, UserHandleCompat user) {
- return getIcon(intent, null, user, true);
+ application.title = entry.title;
+ application.iconBitmap = entry.icon;
+ application.contentDescription = entry.contentDescription;
}
- private Bitmap getIcon(Intent intent, String title, UserHandleCompat user, boolean usePkgIcon) {
- synchronized (mCache) {
- ComponentName component = intent.getComponent();
- // null info means not installed, but if we have a component from the intent then
- // we should still look in the cache for restored app icons.
- if (component == null) {
- return getDefaultIcon(user);
- }
-
- LauncherActivityInfoCompat launcherActInfo = mLauncherApps.resolveActivity(intent, user);
- CacheEntry entry = cacheLocked(component, launcherActInfo, null, user, usePkgIcon);
- if (title != null) {
- entry.title = title;
- entry.contentDescription = mUserManager.getBadgedLabelForUser(title, user);
- }
- return entry.icon;
+ public synchronized Bitmap getIcon(Intent intent, UserHandleCompat user) {
+ ComponentName component = intent.getComponent();
+ // null info means not installed, but if we have a component from the intent then
+ // we should still look in the cache for restored app icons.
+ if (component == null) {
+ return getDefaultIcon(user);
}
+
+ LauncherActivityInfoCompat launcherActInfo = mLauncherApps.resolveActivity(intent, user);
+ CacheEntry entry = cacheLocked(component, launcherActInfo, null, user, true);
+ return entry.icon;
}
/**
* Fill in "shortcutInfo" with the icon and label for "info."
*/
- public void getTitleAndIcon(ShortcutInfo shortcutInfo, Intent intent, UserHandleCompat user,
- boolean usePkgIcon) {
- synchronized (mCache) {
- ComponentName component = intent.getComponent();
- // null info means not installed, but if we have a component from the intent then
- // we should still look in the cache for restored app icons.
- if (component == null) {
- shortcutInfo.setIcon(getDefaultIcon(user));
- shortcutInfo.title = "";
- shortcutInfo.usingFallbackIcon = true;
- } else {
- LauncherActivityInfoCompat launcherActInfo =
- mLauncherApps.resolveActivity(intent, user);
- CacheEntry entry = cacheLocked(component, launcherActInfo, null, user, usePkgIcon);
+ public synchronized void getTitleAndIcon(ShortcutInfo shortcutInfo, Intent intent,
+ UserHandleCompat user, boolean usePkgIcon) {
+ ComponentName component = intent.getComponent();
+ // null info means not installed, but if we have a component from the intent then
+ // we should still look in the cache for restored app icons.
+ if (component == null) {
+ shortcutInfo.setIcon(getDefaultIcon(user));
+ shortcutInfo.title = "";
+ shortcutInfo.usingFallbackIcon = true;
+ } else {
+ LauncherActivityInfoCompat launcherActInfo =
+ mLauncherApps.resolveActivity(intent, user);
+ CacheEntry entry = cacheLocked(component, launcherActInfo, null, user, usePkgIcon);
- shortcutInfo.setIcon(entry.icon);
- shortcutInfo.title = entry.title;
- shortcutInfo.usingFallbackIcon = isDefaultIcon(entry.icon, user);
- }
+ shortcutInfo.setIcon(entry.icon);
+ shortcutInfo.title = entry.title;
+ shortcutInfo.usingFallbackIcon = isDefaultIcon(entry.icon, user);
}
}
- public Bitmap getDefaultIcon(UserHandleCompat user) {
+ public synchronized Bitmap getDefaultIcon(UserHandleCompat user) {
if (!mDefaultIcons.containsKey(user)) {
mDefaultIcons.put(user, makeDefaultIcon(user));
}
return mDefaultIcons.get(user);
}
- public Bitmap getIcon(ComponentName component, LauncherActivityInfoCompat info,
+ public synchronized Bitmap getIcon(ComponentName component, LauncherActivityInfoCompat info,
HashMap<Object, CharSequence> labelCache) {
- synchronized (mCache) {
- if (info == null || component == null) {
- return null;
- }
-
- CacheEntry entry = cacheLocked(component, info, labelCache, info.getUser(), false);
- return entry.icon;
+ if (info == null || component == null) {
+ return null;
}
+
+ CacheEntry entry = cacheLocked(component, info, labelCache, info.getUser(), false);
+ return entry.icon;
}
public boolean isDefaultIcon(Bitmap icon, UserHandleCompat user) {
return mDefaultIcons.get(user) == icon;
}
+ /**
+ * Retrieves the entry from the cache. If the entry is not present, it creates a new entry.
+ * This method is not thread safe, it must be called from a synchronized method.
+ */
private CacheEntry cacheLocked(ComponentName componentName, LauncherActivityInfoCompat info,
HashMap<Object, CharSequence> labelCache, UserHandleCompat user, boolean usePackageIcon) {
CacheKey cacheKey = new CacheKey(componentName, user);
@@ -381,7 +355,7 @@ public class IconCache {
* Adds a default package entry in the cache. This entry is not persisted and will be removed
* when the cache is flushed.
*/
- public void cachePackageInstallInfo(String packageName, UserHandleCompat user,
+ public synchronized void cachePackageInstallInfo(String packageName, UserHandleCompat user,
Bitmap icon, CharSequence title) {
remove(packageName, user);
@@ -390,16 +364,16 @@ public class IconCache {
entry.title = title;
}
if (icon != null) {
- entry.icon = Utilities.createIconBitmap(
- new BitmapDrawable(mContext.getResources(), icon), mContext);
+ entry.icon = Utilities.createIconBitmap(icon, mContext);
}
}
/**
* Gets an entry for the package, which can be used as a fallback entry for various components.
+ * This method is not thread safe, it must be called from a synchronized method.
*/
private CacheEntry getEntryForPackage(String packageName, UserHandleCompat user) {
- ComponentName cn = getPackageComponent(packageName);
+ ComponentName cn = new ComponentName(packageName, EMPTY_CLASS_NAME);;
CacheKey cacheKey = new CacheKey(cn, user);
CacheEntry entry = mCache.get(cacheKey);
if (entry == null) {
@@ -422,15 +396,13 @@ public class IconCache {
return entry;
}
- public HashMap<ComponentName,Bitmap> getAllIcons() {
- synchronized (mCache) {
- HashMap<ComponentName,Bitmap> set = new HashMap<ComponentName,Bitmap>();
- for (CacheKey ck : mCache.keySet()) {
- final CacheEntry e = mCache.get(ck);
- set.put(ck.componentName, e.icon);
- }
- return set;
+ public synchronized HashMap<ComponentName,Bitmap> getAllIcons() {
+ HashMap<ComponentName,Bitmap> set = new HashMap<ComponentName,Bitmap>();
+ for (CacheKey ck : mCache.keySet()) {
+ final CacheEntry e = mCache.get(ck);
+ set.put(ck.componentName, e.icon);
}
+ return set;
}
/**
@@ -536,23 +508,15 @@ public class IconCache {
* Remove a pre-loaded icon from the persistent icon cache.
*
* @param componentName the component that should own the icon
- * @returns true on success
*/
- public boolean deletePreloadedIcon(ComponentName componentName, UserHandleCompat user) {
+ public void deletePreloadedIcon(ComponentName componentName, UserHandleCompat user) {
// We don't keep icons for other profiles in persistent cache.
- if (!user.equals(UserHandleCompat.myUserHandle())) {
- return false;
- }
- if (componentName == null) {
- return false;
- }
- if (mCache.remove(componentName) != null) {
- if (DEBUG) Log.d(TAG, "removed pre-loaded icon from the in-memory cache");
+ if (!user.equals(UserHandleCompat.myUserHandle()) || componentName == null) {
+ return;
}
+ remove(componentName, user);
boolean success = mContext.deleteFile(getResourceFilename(componentName));
if (DEBUG && success) Log.d(TAG, "removed pre-loaded icon from persistent cache");
-
- return success;
}
private static String getResourceFilename(ComponentName component) {
@@ -560,8 +524,4 @@ public class IconCache {
String filename = resourceName.replace(File.separatorChar, '_');
return RESOURCE_FILE_PREFIX + filename;
}
-
- static ComponentName getPackageComponent(String packageName) {
- return new ComponentName(packageName, EMPTY_CLASS_NAME);
- }
}
diff --git a/src/com/android/launcher3/InsettableFrameLayout.java b/src/com/android/launcher3/InsettableFrameLayout.java
new file mode 100644
index 000000000..7343bf686
--- /dev/null
+++ b/src/com/android/launcher3/InsettableFrameLayout.java
@@ -0,0 +1,96 @@
+package com.android.launcher3;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Rect;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+
+public class InsettableFrameLayout extends FrameLayout implements
+ ViewGroup.OnHierarchyChangeListener, Insettable {
+
+ protected Rect mInsets = new Rect();
+
+ public InsettableFrameLayout(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ setOnHierarchyChangeListener(this);
+ }
+
+ public void setFrameLayoutChildInsets(View child, Rect newInsets, Rect oldInsets) {
+ final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+
+ if (child instanceof Insettable) {
+ ((Insettable) child).setInsets(newInsets);
+ } else if (!lp.ignoreInsets) {
+ lp.topMargin += (newInsets.top - oldInsets.top);
+ lp.leftMargin += (newInsets.left - oldInsets.left);
+ lp.rightMargin += (newInsets.right - oldInsets.right);
+ lp.bottomMargin += (newInsets.bottom - oldInsets.bottom);
+ }
+ child.setLayoutParams(lp);
+ }
+
+ @Override
+ public void setInsets(Rect insets) {
+ final int n = getChildCount();
+ for (int i = 0; i < n; i++) {
+ final View child = getChildAt(i);
+ setFrameLayoutChildInsets(child, insets, mInsets);
+ }
+ mInsets.set(insets);
+ }
+
+ @Override
+ public LayoutParams generateLayoutParams(AttributeSet attrs) {
+ return new InsettableFrameLayout.LayoutParams(getContext(), attrs);
+ }
+
+ @Override
+ protected LayoutParams generateDefaultLayoutParams() {
+ return new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
+ }
+
+ // Override to allow type-checking of LayoutParams.
+ @Override
+ protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
+ return p instanceof InsettableFrameLayout.LayoutParams;
+ }
+
+ @Override
+ protected LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
+ return new LayoutParams(p);
+ }
+
+ public static class LayoutParams extends FrameLayout.LayoutParams {
+ boolean ignoreInsets = false;
+
+ public LayoutParams(Context c, AttributeSet attrs) {
+ super(c, attrs);
+ TypedArray a = c.obtainStyledAttributes(attrs,
+ R.styleable.InsettableFrameLayout_Layout);
+ ignoreInsets = a.getBoolean(
+ R.styleable.InsettableFrameLayout_Layout_layout_ignoreInsets, false);
+ a.recycle();
+ }
+
+ public LayoutParams(int width, int height) {
+ super(width, height);
+ }
+
+ public LayoutParams(ViewGroup.LayoutParams lp) {
+ super(lp);
+ }
+ }
+
+ @Override
+ public void onChildViewAdded(View parent, View child) {
+ setFrameLayoutChildInsets(child, mInsets, new Rect());
+ }
+
+ @Override
+ public void onChildViewRemoved(View parent, View child) {
+ }
+
+}
diff --git a/src/com/android/launcher3/InstallShortcutReceiver.java b/src/com/android/launcher3/InstallShortcutReceiver.java
index 2edde4fae..1ab308558 100644
--- a/src/com/android/launcher3/InstallShortcutReceiver.java
+++ b/src/com/android/launcher3/InstallShortcutReceiver.java
@@ -17,7 +17,6 @@
package com.android.launcher3;
import android.content.BroadcastReceiver;
-import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
@@ -28,14 +27,18 @@ import android.graphics.BitmapFactory;
import android.text.TextUtils;
import android.util.Base64;
import android.util.Log;
-import android.widget.Toast;
+import com.android.launcher3.compat.LauncherActivityInfoCompat;
+import com.android.launcher3.compat.LauncherAppsCompat;
import com.android.launcher3.compat.UserHandleCompat;
+import com.android.launcher3.compat.UserManagerCompat;
+import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONStringer;
import org.json.JSONTokener;
+import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
@@ -45,80 +48,52 @@ public class InstallShortcutReceiver extends BroadcastReceiver {
private static final String TAG = "InstallShortcutReceiver";
private static final boolean DBG = false;
- public static final String ACTION_INSTALL_SHORTCUT =
+ private static final String ACTION_INSTALL_SHORTCUT =
"com.android.launcher.action.INSTALL_SHORTCUT";
- public static final String DATA_INTENT_KEY = "intent.data";
- public static final String LAUNCH_INTENT_KEY = "intent.launch";
- public static final String NAME_KEY = "name";
- public static final String ICON_KEY = "icon";
- public static final String ICON_RESOURCE_NAME_KEY = "iconResource";
- public static final String ICON_RESOURCE_PACKAGE_NAME_KEY = "iconResourcePackage";
+ private static final String LAUNCH_INTENT_KEY = "intent.launch";
+ private static final String NAME_KEY = "name";
+ private static final String ICON_KEY = "icon";
+ private static final String ICON_RESOURCE_NAME_KEY = "iconResource";
+ private static final String ICON_RESOURCE_PACKAGE_NAME_KEY = "iconResourcePackage";
+
+ private static final String APP_SHORTCUT_TYPE_KEY = "isAppShortcut";
+ private static final String USER_HANDLE_KEY = "userHandle";
+
// The set of shortcuts that are pending install
- public static final String APPS_PENDING_INSTALL = "apps_to_install";
+ private static final String APPS_PENDING_INSTALL = "apps_to_install";
public static final int NEW_SHORTCUT_BOUNCE_DURATION = 450;
public static final int NEW_SHORTCUT_STAGGER_DELAY = 85;
- private static final int INSTALL_SHORTCUT_SUCCESSFUL = 0;
- private static final int INSTALL_SHORTCUT_IS_DUPLICATE = -1;
-
- // A mime-type representing shortcut data
- public static final String SHORTCUT_MIMETYPE =
- "com.android.launcher3/shortcut";
-
- private static Object sLock = new Object();
-
- private static void addToStringSet(SharedPreferences sharedPrefs,
- SharedPreferences.Editor editor, String key, String value) {
- Set<String> strings = sharedPrefs.getStringSet(key, null);
- if (strings == null) {
- strings = new HashSet<String>(0);
- } else {
- strings = new HashSet<String>(strings);
- }
- strings.add(value);
- editor.putStringSet(key, strings);
- }
+ private static final Object sLock = new Object();
private static void addToInstallQueue(
SharedPreferences sharedPrefs, PendingInstallShortcutInfo info) {
synchronized(sLock) {
- try {
- JSONStringer json = new JSONStringer()
- .object()
- .key(DATA_INTENT_KEY).value(info.data.toUri(0))
- .key(LAUNCH_INTENT_KEY).value(info.launchIntent.toUri(0))
- .key(NAME_KEY).value(info.name);
- if (info.icon != null) {
- byte[] iconByteArray = ItemInfo.flattenBitmap(info.icon);
- json = json.key(ICON_KEY).value(
- Base64.encodeToString(
- iconByteArray, 0, iconByteArray.length, Base64.DEFAULT));
- }
- if (info.iconResource != null) {
- json = json.key(ICON_RESOURCE_NAME_KEY).value(info.iconResource.resourceName);
- json = json.key(ICON_RESOURCE_PACKAGE_NAME_KEY)
- .value(info.iconResource.packageName);
+ String encoded = info.encodeToString();
+ if (encoded != null) {
+ Set<String> strings = sharedPrefs.getStringSet(APPS_PENDING_INSTALL, null);
+ if (strings == null) {
+ strings = new HashSet<String>(1);
+ } else {
+ strings = new HashSet<String>(strings);
}
- json = json.endObject();
- SharedPreferences.Editor editor = sharedPrefs.edit();
- if (DBG) Log.d(TAG, "Adding to APPS_PENDING_INSTALL: " + json);
- addToStringSet(sharedPrefs, editor, APPS_PENDING_INSTALL, json.toString());
- editor.commit();
- } catch (org.json.JSONException e) {
- Log.d(TAG, "Exception when adding shortcut: " + e);
+ strings.add(encoded);
+ sharedPrefs.edit().putStringSet(APPS_PENDING_INSTALL, strings).commit();
}
}
}
- public static void removeFromInstallQueue(SharedPreferences sharedPrefs,
- ArrayList<String> packageNames) {
+ public static void removeFromInstallQueue(Context context, ArrayList<String> packageNames,
+ UserHandleCompat user) {
if (packageNames.isEmpty()) {
return;
}
+ String spKey = LauncherAppState.getSharedPreferencesKey();
+ SharedPreferences sp = context.getSharedPreferences(spKey, Context.MODE_PRIVATE);
synchronized(sLock) {
- Set<String> strings = sharedPrefs.getStringSet(APPS_PENDING_INSTALL, null);
+ Set<String> strings = sp.getStringSet(APPS_PENDING_INSTALL, null);
if (DBG) {
Log.d(TAG, "APPS_PENDING_INSTALL: " + strings
+ ", removing packages: " + packageNames);
@@ -127,31 +102,20 @@ public class InstallShortcutReceiver extends BroadcastReceiver {
Set<String> newStrings = new HashSet<String>(strings);
Iterator<String> newStringsIter = newStrings.iterator();
while (newStringsIter.hasNext()) {
- String json = newStringsIter.next();
- try {
- JSONObject object = (JSONObject) new JSONTokener(json).nextValue();
- Intent launchIntent = Intent.parseUri(object.getString(LAUNCH_INTENT_KEY), 0);
- String pn = launchIntent.getPackage();
- if (pn == null) {
- pn = launchIntent.getComponent().getPackageName();
- }
- if (packageNames.contains(pn)) {
- newStringsIter.remove();
- }
- } catch (org.json.JSONException e) {
- Log.d(TAG, "Exception reading shortcut to remove: " + e);
- } catch (java.net.URISyntaxException e) {
- Log.d(TAG, "Exception reading shortcut to remove: " + e);
+ String encoded = newStringsIter.next();
+ PendingInstallShortcutInfo info = decode(encoded, context);
+ if (info == null || (packageNames.contains(info.getTargetPackage())
+ && user.equals(info.user))) {
+ newStringsIter.remove();
}
}
- sharedPrefs.edit().putStringSet(APPS_PENDING_INSTALL,
- new HashSet<String>(newStrings)).commit();
+ sp.edit().putStringSet(APPS_PENDING_INSTALL, newStrings).commit();
}
}
}
private static ArrayList<PendingInstallShortcutInfo> getAndClearInstallQueue(
- SharedPreferences sharedPrefs) {
+ SharedPreferences sharedPrefs, Context context) {
synchronized(sLock) {
Set<String> strings = sharedPrefs.getStringSet(APPS_PENDING_INSTALL, null);
if (DBG) Log.d(TAG, "Getting and clearing APPS_PENDING_INSTALL: " + strings);
@@ -160,36 +124,10 @@ public class InstallShortcutReceiver extends BroadcastReceiver {
}
ArrayList<PendingInstallShortcutInfo> infos =
new ArrayList<PendingInstallShortcutInfo>();
- for (String json : strings) {
- try {
- JSONObject object = (JSONObject) new JSONTokener(json).nextValue();
- Intent data = Intent.parseUri(object.getString(DATA_INTENT_KEY), 0);
- Intent launchIntent =
- Intent.parseUri(object.getString(LAUNCH_INTENT_KEY), 0);
- String name = object.getString(NAME_KEY);
- String iconBase64 = object.optString(ICON_KEY);
- String iconResourceName = object.optString(ICON_RESOURCE_NAME_KEY);
- String iconResourcePackageName =
- object.optString(ICON_RESOURCE_PACKAGE_NAME_KEY);
- if (iconBase64 != null && !iconBase64.isEmpty()) {
- byte[] iconArray = Base64.decode(iconBase64, Base64.DEFAULT);
- Bitmap b = BitmapFactory.decodeByteArray(iconArray, 0, iconArray.length);
- data.putExtra(Intent.EXTRA_SHORTCUT_ICON, b);
- } else if (iconResourceName != null && !iconResourceName.isEmpty()) {
- Intent.ShortcutIconResource iconResource =
- new Intent.ShortcutIconResource();
- iconResource.resourceName = iconResourceName;
- iconResource.packageName = iconResourcePackageName;
- data.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, iconResource);
- }
- data.putExtra(Intent.EXTRA_SHORTCUT_INTENT, launchIntent);
- PendingInstallShortcutInfo info =
- new PendingInstallShortcutInfo(data, name, launchIntent);
+ for (String encoded : strings) {
+ PendingInstallShortcutInfo info = decode(encoded, context);
+ if (info != null) {
infos.add(info);
- } catch (org.json.JSONException e) {
- Log.d(TAG, "Exception reading shortcut to add: " + e);
- } catch (java.net.URISyntaxException e) {
- Log.d(TAG, "Exception reading shortcut to add: " + e);
}
}
sharedPrefs.edit().putStringSet(APPS_PENDING_INSTALL, new HashSet<String>()).commit();
@@ -201,49 +139,26 @@ public class InstallShortcutReceiver extends BroadcastReceiver {
// processAllPendingInstalls() is called.
private static boolean mUseInstallQueue = false;
- private static class PendingInstallShortcutInfo {
- Intent data;
- Intent launchIntent;
- String name;
- Bitmap icon;
- Intent.ShortcutIconResource iconResource;
-
- public PendingInstallShortcutInfo(Intent rawData, String shortcutName,
- Intent shortcutIntent) {
- data = rawData;
- name = shortcutName;
- launchIntent = shortcutIntent;
- }
- }
-
public void onReceive(Context context, Intent data) {
if (!ACTION_INSTALL_SHORTCUT.equals(data.getAction())) {
return;
}
if (DBG) Log.d(TAG, "Got INSTALL_SHORTCUT: " + data.toUri(0));
+ PendingInstallShortcutInfo info = new PendingInstallShortcutInfo(data, context);
- Intent intent = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT);
- if (intent == null) {
- return;
- }
+ queuePendingShortcutInfo(info, context);
+ }
- // This name is only used for comparisons and notifications, so fall back to activity name
- // if not supplied
- String name = ensureValidName(context, intent,
- data.getStringExtra(Intent.EXTRA_SHORTCUT_NAME)).toString();
- Bitmap icon = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_ICON);
- Intent.ShortcutIconResource iconResource =
- data.getParcelableExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE);
+ static void queueInstallShortcut(LauncherActivityInfoCompat info, Context context) {
+ queuePendingShortcutInfo(new PendingInstallShortcutInfo(info, context), context);
+ }
+ private static void queuePendingShortcutInfo(PendingInstallShortcutInfo info, Context context) {
// Queue the item up for adding if launcher has not loaded properly yet
LauncherAppState.setApplicationContext(context.getApplicationContext());
LauncherAppState app = LauncherAppState.getInstance();
- boolean launcherNotLoaded = (app.getDynamicGrid() == null);
-
- PendingInstallShortcutInfo info = new PendingInstallShortcutInfo(data, name, intent);
- info.icon = icon;
- info.iconResource = iconResource;
+ boolean launcherNotLoaded = app.getModel().getCallback() == null;
String spKey = LauncherAppState.getSharedPreferencesKey();
SharedPreferences sp = context.getSharedPreferences(spKey, Context.MODE_PRIVATE);
@@ -263,33 +178,22 @@ public class InstallShortcutReceiver extends BroadcastReceiver {
static void flushInstallQueue(Context context) {
String spKey = LauncherAppState.getSharedPreferencesKey();
SharedPreferences sp = context.getSharedPreferences(spKey, Context.MODE_PRIVATE);
- ArrayList<PendingInstallShortcutInfo> installQueue = getAndClearInstallQueue(sp);
+ ArrayList<PendingInstallShortcutInfo> installQueue = getAndClearInstallQueue(sp, context);
if (!installQueue.isEmpty()) {
Iterator<PendingInstallShortcutInfo> iter = installQueue.iterator();
ArrayList<ItemInfo> addShortcuts = new ArrayList<ItemInfo>();
- int result = INSTALL_SHORTCUT_SUCCESSFUL;
- String duplicateName = "";
while (iter.hasNext()) {
final PendingInstallShortcutInfo pendingInfo = iter.next();
- //final Intent data = pendingInfo.data;
final Intent intent = pendingInfo.launchIntent;
- final String name = pendingInfo.name;
if (LauncherAppState.isDisableAllApps() && !isValidShortcutLaunchIntent(intent)) {
if (DBG) Log.d(TAG, "Ignoring shortcut with launchIntent:" + intent);
continue;
}
- final boolean exists = LauncherModel.shortcutExists(context, name, intent);
- //final boolean allowDuplicate = data.getBooleanExtra(Launcher.EXTRA_SHORTCUT_DUPLICATE, true);
-
// If the intent specifies a package, make sure the package exists
- String packageName = intent.getPackage();
- if (packageName == null) {
- packageName = intent.getComponent() == null ? null :
- intent.getComponent().getPackageName();
- }
- if (packageName != null && !packageName.isEmpty()) {
+ String packageName = pendingInfo.getTargetPackage();
+ if (!TextUtils.isEmpty(packageName)) {
UserHandleCompat myUserHandle = UserHandleCompat.myUserHandle();
if (!LauncherModel.isValidPackage(context, packageName, myUserHandle)) {
if (DBG) Log.d(TAG, "Ignoring shortcut for absent package:" + intent);
@@ -297,19 +201,12 @@ public class InstallShortcutReceiver extends BroadcastReceiver {
}
}
+ final boolean exists = LauncherModel.shortcutExists(context, pendingInfo.label,
+ intent, pendingInfo.user);
if (!exists) {
// Generate a shortcut info to add into the model
- ShortcutInfo info = getShortcutInfo(context, pendingInfo.data,
- pendingInfo.launchIntent);
- addShortcuts.add(info);
+ addShortcuts.add(pendingInfo.getShortcutInfo());
}
-
- }
-
- // Notify the user once if we weren't able to place any duplicates
- if (result == INSTALL_SHORTCUT_IS_DUPLICATE) {
- Toast.makeText(context, context.getString(R.string.shortcut_duplicate,
- duplicateName), Toast.LENGTH_SHORT).show();
}
// Add the new apps to the model and bind them
@@ -344,22 +241,6 @@ public class InstallShortcutReceiver extends BroadcastReceiver {
return true;
}
- private static ShortcutInfo getShortcutInfo(Context context, Intent data,
- Intent launchIntent) {
- if (launchIntent.getAction() == null) {
- launchIntent.setAction(Intent.ACTION_VIEW);
- } else if (launchIntent.getAction().equals(Intent.ACTION_MAIN) &&
- launchIntent.getCategories() != null &&
- launchIntent.getCategories().contains(Intent.CATEGORY_LAUNCHER)) {
- launchIntent.addFlags(
- Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
- }
- LauncherAppState app = LauncherAppState.getInstance();
- ShortcutInfo info = app.getModel().infoFromShortcutIntent(context, data, null);
- info.title = ensureValidName(context, launchIntent, info.title);
- return info;
- }
-
/**
* Ensures that we have a valid, non-null name. If the provided name is null, we will return
* the application name instead.
@@ -376,4 +257,171 @@ public class InstallShortcutReceiver extends BroadcastReceiver {
}
return name;
}
+
+ private static class PendingInstallShortcutInfo {
+
+ final LauncherActivityInfoCompat activityInfo;
+
+ final Intent data;
+ final Context mContext;
+ final Intent launchIntent;
+ final String label;
+ final UserHandleCompat user;
+
+ /**
+ * Initializes a PendingInstallShortcutInfo received from a different app.
+ */
+ public PendingInstallShortcutInfo(Intent data, Context context) {
+ this.data = data;
+ mContext = context;
+
+ launchIntent = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT);
+ label = data.getStringExtra(Intent.EXTRA_SHORTCUT_NAME);
+ user = UserHandleCompat.myUserHandle();
+ activityInfo = null;
+ }
+
+ /**
+ * Initializes a PendingInstallShortcutInfo to represent a launcher target.
+ */
+ public PendingInstallShortcutInfo(LauncherActivityInfoCompat info, Context context) {
+ this.data = null;
+ mContext = context;
+ activityInfo = info;
+ user = info.getUser();
+
+ launchIntent = AppInfo.makeLaunchIntent(context, info, user);
+ label = info.getLabel().toString();
+ }
+
+ public String encodeToString() {
+ if (activityInfo != null) {
+ try {
+ // If it a launcher target, we only need component name, and user to
+ // recreate this.
+ return new JSONStringer()
+ .object()
+ .key(LAUNCH_INTENT_KEY).value(launchIntent.toUri(0))
+ .key(APP_SHORTCUT_TYPE_KEY).value(true)
+ .key(USER_HANDLE_KEY).value(UserManagerCompat.getInstance(mContext)
+ .getSerialNumberForUser(user))
+ .endObject().toString();
+ } catch (JSONException e) {
+ Log.d(TAG, "Exception when adding shortcut: " + e);
+ return null;
+ }
+ }
+
+ if (launchIntent.getAction() == null) {
+ launchIntent.setAction(Intent.ACTION_VIEW);
+ } else if (launchIntent.getAction().equals(Intent.ACTION_MAIN) &&
+ launchIntent.getCategories() != null &&
+ launchIntent.getCategories().contains(Intent.CATEGORY_LAUNCHER)) {
+ launchIntent.addFlags(
+ Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
+ }
+
+ // This name is only used for comparisons and notifications, so fall back to activity
+ // name if not supplied
+ String name = ensureValidName(mContext, launchIntent, label).toString();
+ Bitmap icon = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_ICON);
+ Intent.ShortcutIconResource iconResource =
+ data.getParcelableExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE);
+
+ // Only encode the parameters which are supported by the API.
+ try {
+ JSONStringer json = new JSONStringer()
+ .object()
+ .key(LAUNCH_INTENT_KEY).value(launchIntent.toUri(0))
+ .key(NAME_KEY).value(name);
+ if (icon != null) {
+ byte[] iconByteArray = ItemInfo.flattenBitmap(icon);
+ json = json.key(ICON_KEY).value(
+ Base64.encodeToString(
+ iconByteArray, 0, iconByteArray.length, Base64.DEFAULT));
+ }
+ if (iconResource != null) {
+ json = json.key(ICON_RESOURCE_NAME_KEY).value(iconResource.resourceName);
+ json = json.key(ICON_RESOURCE_PACKAGE_NAME_KEY)
+ .value(iconResource.packageName);
+ }
+ return json.endObject().toString();
+ } catch (JSONException e) {
+ Log.d(TAG, "Exception when adding shortcut: " + e);
+ }
+ return null;
+ }
+
+ public ShortcutInfo getShortcutInfo() {
+ if (activityInfo != null) {
+ final ShortcutInfo info = new ShortcutInfo();
+ info.user = user;
+ info.title = label;
+ info.contentDescription = label;
+ info.customIcon = false;
+ info.intent = launchIntent;
+ info.itemType = LauncherSettings.Favorites.ITEM_TYPE_APPLICATION;
+ info.flags = AppInfo.initFlags(activityInfo);
+ info.firstInstallTime = activityInfo.getFirstInstallTime();
+ return info;
+ } else {
+ return LauncherAppState.getInstance().getModel().infoFromShortcutIntent(mContext, data);
+ }
+ }
+
+ public String getTargetPackage() {
+ String packageName = launchIntent.getPackage();
+ if (packageName == null) {
+ packageName = launchIntent.getComponent() == null ? null :
+ launchIntent.getComponent().getPackageName();
+ }
+ return packageName;
+ }
+ }
+
+ private static PendingInstallShortcutInfo decode(String encoded, Context context) {
+ try {
+ JSONObject object = (JSONObject) new JSONTokener(encoded).nextValue();
+ Intent launcherIntent = Intent.parseUri(object.getString(LAUNCH_INTENT_KEY), 0);
+
+ if (object.optBoolean(APP_SHORTCUT_TYPE_KEY)) {
+ // The is an internal launcher target shortcut.
+ UserHandleCompat user = UserManagerCompat.getInstance(context)
+ .getUserForSerialNumber(object.getLong(USER_HANDLE_KEY));
+ if (user == null) {
+ return null;
+ }
+
+ LauncherActivityInfoCompat info = LauncherAppsCompat.getInstance(context)
+ .resolveActivity(launcherIntent, user);
+ return info == null ? null : new PendingInstallShortcutInfo(info, context);
+ }
+
+ Intent data = new Intent();
+ data.putExtra(Intent.EXTRA_SHORTCUT_INTENT, launcherIntent);
+ data.putExtra(Intent.EXTRA_SHORTCUT_NAME, object.getString(NAME_KEY));
+
+ String iconBase64 = object.optString(ICON_KEY);
+ String iconResourceName = object.optString(ICON_RESOURCE_NAME_KEY);
+ String iconResourcePackageName = object.optString(ICON_RESOURCE_PACKAGE_NAME_KEY);
+ if (iconBase64 != null && !iconBase64.isEmpty()) {
+ byte[] iconArray = Base64.decode(iconBase64, Base64.DEFAULT);
+ Bitmap b = BitmapFactory.decodeByteArray(iconArray, 0, iconArray.length);
+ data.putExtra(Intent.EXTRA_SHORTCUT_ICON, b);
+ } else if (iconResourceName != null && !iconResourceName.isEmpty()) {
+ Intent.ShortcutIconResource iconResource =
+ new Intent.ShortcutIconResource();
+ iconResource.resourceName = iconResourceName;
+ iconResource.packageName = iconResourcePackageName;
+ data.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, iconResource);
+ }
+
+ return new PendingInstallShortcutInfo(data, context);
+ } catch (JSONException e) {
+ Log.d(TAG, "Exception reading shortcut to add: " + e);
+ } catch (URISyntaxException e) {
+ Log.d(TAG, "Exception reading shortcut to add: " + e);
+ }
+ return null;
+ }
}
diff --git a/src/com/android/launcher3/InstallWidgetReceiver.java b/src/com/android/launcher3/InstallWidgetReceiver.java
deleted file mode 100644
index 74b9e3d99..000000000
--- a/src/com/android/launcher3/InstallWidgetReceiver.java
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Copyright (C) 2010 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.launcher3;
-
-import android.appwidget.AppWidgetProviderInfo;
-import android.content.ClipData;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.database.DataSetObserver;
-import android.graphics.drawable.Drawable;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ImageView;
-import android.widget.ListAdapter;
-import android.widget.TextView;
-
-import java.util.List;
-
-
-/**
- * We will likely flesh this out later, to handle allow external apps to place widgets, but for now,
- * we just want to expose the action around for checking elsewhere.
- */
-public class InstallWidgetReceiver {
- public static final String ACTION_INSTALL_WIDGET =
- "com.android.launcher3.action.INSTALL_WIDGET";
- public static final String ACTION_SUPPORTS_CLIPDATA_MIMETYPE =
- "com.android.launcher3.action.SUPPORTS_CLIPDATA_MIMETYPE";
-
- // Currently not exposed. Put into Intent when we want to make it public.
- // TEMP: Should we call this "EXTRA_APPWIDGET_PROVIDER"?
- public static final String EXTRA_APPWIDGET_COMPONENT =
- "com.android.launcher3.extra.widget.COMPONENT";
- public static final String EXTRA_APPWIDGET_CONFIGURATION_DATA_MIME_TYPE =
- "com.android.launcher3.extra.widget.CONFIGURATION_DATA_MIME_TYPE";
- public static final String EXTRA_APPWIDGET_CONFIGURATION_DATA =
- "com.android.launcher3.extra.widget.CONFIGURATION_DATA";
-
- /**
- * A simple data class that contains per-item information that the adapter below can reference.
- */
- public static class WidgetMimeTypeHandlerData {
- public ResolveInfo resolveInfo;
- public AppWidgetProviderInfo widgetInfo;
-
- public WidgetMimeTypeHandlerData(ResolveInfo rInfo, AppWidgetProviderInfo wInfo) {
- resolveInfo = rInfo;
- widgetInfo = wInfo;
- }
- }
-
- /**
- * The ListAdapter which presents all the valid widgets that can be created for a given drop.
- */
- public static class WidgetListAdapter implements ListAdapter, DialogInterface.OnClickListener {
- private LayoutInflater mInflater;
- private Launcher mLauncher;
- private String mMimeType;
- private ClipData mClipData;
- private List<WidgetMimeTypeHandlerData> mActivities;
- private int mTargetLayoutScreen;
- private int[] mTargetLayoutPos;
-
- public WidgetListAdapter(Launcher l, String mimeType, ClipData data,
- List<WidgetMimeTypeHandlerData> list, int targetScreen, int[] targetPos) {
- mLauncher = l;
- mMimeType = mimeType;
- mClipData = data;
- mActivities = list;
- mTargetLayoutScreen = targetScreen;
- mTargetLayoutPos = targetPos;
- }
-
- @Override
- public void registerDataSetObserver(DataSetObserver observer) {
- }
-
- @Override
- public void unregisterDataSetObserver(DataSetObserver observer) {
- }
-
- @Override
- public int getCount() {
- return mActivities.size();
- }
-
- @Override
- public Object getItem(int position) {
- return null;
- }
-
- @Override
- public long getItemId(int position) {
- return position;
- }
-
- @Override
- public boolean hasStableIds() {
- return true;
- }
-
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- final Context context = parent.getContext();
- final PackageManager packageManager = context.getPackageManager();
-
- // Lazy-create inflater
- if (mInflater == null) {
- mInflater = LayoutInflater.from(context);
- }
-
- // Use the convert-view where possible
- if (convertView == null) {
- convertView = mInflater.inflate(R.layout.external_widget_drop_list_item, parent,
- false);
- }
-
- final WidgetMimeTypeHandlerData data = mActivities.get(position);
- final ResolveInfo resolveInfo = data.resolveInfo;
- final AppWidgetProviderInfo widgetInfo = data.widgetInfo;
-
- // Set the icon
- Drawable d = resolveInfo.loadIcon(packageManager);
- ImageView i = (ImageView) convertView.findViewById(R.id.provider_icon);
- i.setImageDrawable(d);
-
- // Set the text
- final CharSequence component = resolveInfo.loadLabel(packageManager);
- final int[] widgetSpan = new int[2];
- CellLayout.rectToCell(widgetInfo.minWidth, widgetInfo.minHeight, widgetSpan);
- TextView t = (TextView) convertView.findViewById(R.id.provider);
- t.setText(context.getString(R.string.external_drop_widget_pick_format,
- component, widgetSpan[0], widgetSpan[1]));
-
- return convertView;
- }
-
- @Override
- public int getItemViewType(int position) {
- return 0;
- }
-
- @Override
- public int getViewTypeCount() {
- return 1;
- }
-
- @Override
- public boolean isEmpty() {
- return mActivities.isEmpty();
- }
-
- @Override
- public boolean areAllItemsEnabled() {
- return false;
- }
-
- @Override
- public boolean isEnabled(int position) {
- return true;
- }
-
- @Override
- public void onClick(DialogInterface dialog, int which) {
- final AppWidgetProviderInfo widgetInfo = mActivities.get(which).widgetInfo;
-
- final PendingAddWidgetInfo createInfo = new PendingAddWidgetInfo(widgetInfo, mMimeType,
- mClipData);
- mLauncher.addAppWidgetFromDrop(createInfo, LauncherSettings.Favorites.CONTAINER_DESKTOP,
- mTargetLayoutScreen, null, null, mTargetLayoutPos);
- }
- }
-}
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 42ec4fb48..ac46fd33d 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -50,10 +50,10 @@ import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.database.ContentObserver;
+import android.database.sqlite.SQLiteDatabase;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
-import android.graphics.Point;
import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
@@ -66,14 +66,11 @@ import android.os.Handler;
import android.os.Message;
import android.os.StrictMode;
import android.os.SystemClock;
-import android.speech.RecognizerIntent;
import android.text.Selection;
import android.text.SpannableStringBuilder;
import android.text.TextUtils;
import android.text.method.TextKeyListener;
-import android.util.DisplayMetrics;
import android.util.Log;
-import android.view.ContextThemeWrapper;
import android.view.Display;
import android.view.Gravity;
import android.view.HapticFeedbackConstants;
@@ -87,19 +84,17 @@ import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.view.ViewAnimationUtils;
import android.view.ViewGroup;
+import android.view.ViewStub;
import android.view.ViewTreeObserver;
-import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.view.Window;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityEvent;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
-import android.view.animation.Interpolator;
import android.view.inputmethod.InputMethodManager;
import android.widget.Advanceable;
import android.widget.FrameLayout;
import android.widget.ImageView;
-import android.widget.TextView;
import android.widget.Toast;
import com.android.launcher3.DropTarget.DragObject;
@@ -128,6 +123,7 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
@@ -168,10 +164,8 @@ public class Launcher extends Activity
static final int SCREEN_COUNT = 5;
static final int DEFAULT_SCREEN = 2;
- private static final String PREFERENCES = "launcher.preferences";
// To turn on these properties, type
// adb shell setprop log.tag.PROPERTY_NAME [VERBOSE | SUPPRESS]
- static final String FORCE_ENABLE_ROTATION_PROPERTY = "launcher_force_rotate";
static final String DUMP_STATE_PROPERTY = "launcher_dump_state";
static final String DISABLE_ALL_APPS_PROPERTY = "launcher_noallapps";
@@ -213,15 +207,12 @@ public class Launcher extends Activity
static final String ACTION_FIRST_LOAD_COMPLETE =
"com.android.launcher3.action.FIRST_LOAD_COMPLETE";
- private static final String TOOLBAR_ICON_METADATA_NAME = "com.android.launcher.toolbar_icon";
- private static final String TOOLBAR_SEARCH_ICON_METADATA_NAME =
- "com.android.launcher.toolbar_search_icon";
- private static final String TOOLBAR_VOICE_SEARCH_ICON_METADATA_NAME =
- "com.android.launcher.toolbar_voice_search_icon";
-
public static final String SHOW_WEIGHT_WATCHER = "debug.show_mem";
public static final boolean SHOW_WEIGHT_WATCHER_DEFAULT = false;
+ private static final String QSB_WIDGET_ID = "qsb_widget_id";
+ private static final String QSB_WIDGET_PROVIDER = "qsb_widget_provider";
+
public static final String USER_HAS_MIGRATED = "launcher.user_migrated_from_old_data";
/** The different states that Launcher can be in. */
@@ -231,6 +222,10 @@ public class Launcher extends Activity
private boolean mIsSafeModeEnabled;
+ LauncherOverlayCallbacks mLauncherOverlayCallbacks = new LauncherOverlayCallbacksImpl();
+ LauncherOverlay mLauncherOverlay;
+ InsettableFrameLayout mLauncherOverlayContainer;
+
static final int APPWIDGET_HOST_ID = 1024;
public static final int EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT = 300;
private static final int ON_ACTIVITY_RESULT_ANIMATION_DELAY = 500;
@@ -281,7 +276,7 @@ public class Launcher extends Activity
private AppsCustomizeTabHost mAppsCustomizeTabHost;
private AppsCustomizePagedView mAppsCustomizeContent;
private boolean mAutoAdvanceRunning = false;
- private View mQsb;
+ private AppWidgetHostView mQsb;
private Bundle mSavedState;
// We set the state in both onCreate and then onNewIntent in some cases, which causes both
@@ -329,10 +324,6 @@ public class Launcher extends Activity
// match the sensor state.
private final int mRestoreScreenOrientationDelay = 500;
- // External icons saved in case of resource changes, orientation, etc.
- private static Drawable.ConstantState[] sGlobalSearchIcon = new Drawable.ConstantState[2];
- private static Drawable.ConstantState[] sVoiceSearchIcon = new Drawable.ConstantState[2];
-
private Drawable mWorkspaceBackgroundDrawable;
private final ArrayList<Integer> mSynchronouslyBoundPages = new ArrayList<Integer>();
@@ -370,8 +361,6 @@ public class Launcher extends Activity
private static PendingAddArguments sPendingAddItem;
- public static boolean sForceEnableRotation = isPropertyEnabled(FORCE_ENABLE_ROTATION_PROPERTY);
-
private static class PendingAddArguments {
int requestCode;
Intent intent;
@@ -386,10 +375,6 @@ public class Launcher extends Activity
FocusIndicatorView mFocusHandler;
- static boolean isPropertyEnabled(String propertyName) {
- return Log.isLoggable(propertyName, Log.VERBOSE);
- }
-
@Override
protected void onCreate(Bundle savedInstanceState) {
if (DEBUG_STRICT_MODE) {
@@ -407,27 +392,18 @@ public class Launcher extends Activity
.build());
}
+ if (mLauncherCallbacks != null) {
+ mLauncherCallbacks.preOnCreate();
+ }
+
super.onCreate(savedInstanceState);
LauncherAppState.setApplicationContext(getApplicationContext());
LauncherAppState app = LauncherAppState.getInstance();
LauncherAppState.getLauncherProvider().setLauncherProviderChangeListener(this);
- // Determine the dynamic grid properties
- Point smallestSize = new Point();
- Point largestSize = new Point();
- Point realSize = new Point();
- Display display = getWindowManager().getDefaultDisplay();
- display.getCurrentSizeRange(smallestSize, largestSize);
- display.getRealSize(realSize);
- DisplayMetrics dm = new DisplayMetrics();
- display.getMetrics(dm);
// Lazy-initialize the dynamic grid
- DeviceProfile grid = app.initDynamicGrid(this,
- Math.min(smallestSize.x, smallestSize.y),
- Math.min(largestSize.x, largestSize.y),
- realSize.x, realSize.y,
- dm.widthPixels, dm.heightPixels);
+ DeviceProfile grid = app.initDynamicGrid(this);
// the LauncherApplication should call this, but in case of Instrumentation it might not be present yet
mSharedPrefs = getSharedPreferences(LauncherAppState.getSharedPreferencesKey(),
@@ -492,11 +468,20 @@ public class Launcher extends Activity
IntentFilter filter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
registerReceiver(mCloseSystemDialogsReceiver, filter);
- updateGlobalIcons();
-
// On large interfaces, we want the screen to auto-rotate based on the current orientation
unlockScreenOrientation(true);
+ if (mLauncherCallbacks != null) {
+ mLauncherCallbacks.onCreate(savedInstanceState);
+ if (mLauncherCallbacks.hasLauncherOverlay()) {
+ ViewStub stub = (ViewStub) findViewById(R.id.launcher_overlay_stub);
+ mLauncherOverlayContainer = (InsettableFrameLayout) stub.inflate();
+ mLauncherOverlay = mLauncherCallbacks.setLauncherOverlayView(
+ mLauncherOverlayContainer, mLauncherOverlayCallbacks);
+ mWorkspace.setLauncherOverlay(mLauncherOverlay);
+ }
+ }
+
if (shouldShowIntroScreen()) {
showIntroScreen();
} else {
@@ -505,11 +490,32 @@ public class Launcher extends Activity
}
}
+ private LauncherCallbacks mLauncherCallbacks;
+
+ public void onPostCreate(Bundle savedInstanceState) {
+ super.onPostCreate(savedInstanceState);
+ if (mLauncherCallbacks != null) {
+ mLauncherCallbacks.onPostCreate(savedInstanceState);
+ }
+ }
+
+ public boolean setLauncherCallbacks(LauncherCallbacks callbacks) {
+ mLauncherCallbacks = callbacks;
+ return true;
+ }
+
@Override
- public void onLauncherProviderChange() { }
+ public void onLauncherProviderChange() {
+ if (mLauncherCallbacks != null) {
+ mLauncherCallbacks.onLauncherProviderChange();
+ }
+ }
- /** To be overriden by subclasses to hint to Launcher that we have custom content */
+ /** To be overridden by subclasses to hint to Launcher that we have custom content */
protected boolean hasCustomContentToLeft() {
+ if (mLauncherCallbacks != null) {
+ return mLauncherCallbacks.hasCustomContentToLeft();
+ }
return false;
}
@@ -519,6 +525,9 @@ public class Launcher extends Activity
* {@link #hasCustomContentToLeft()} is {@code true}.
*/
protected void populateCustomContentContainer() {
+ if (mLauncherCallbacks != null) {
+ mLauncherCallbacks.populateCustomContentContainer();
+ }
}
/**
@@ -540,28 +549,6 @@ public class Launcher extends Activity
}
}
- private void updateGlobalIcons() {
- boolean searchVisible = false;
- boolean voiceVisible = false;
- // If we have a saved version of these external icons, we load them up immediately
- int coi = getCurrentOrientationIndexForGlobalIcons();
- if (sGlobalSearchIcon[coi] == null || sVoiceSearchIcon[coi] == null) {
- searchVisible = updateGlobalSearchIcon();
- voiceVisible = updateVoiceSearchIcon(searchVisible);
- }
- if (sGlobalSearchIcon[coi] != null) {
- updateGlobalSearchIcon(sGlobalSearchIcon[coi]);
- searchVisible = true;
- }
- if (sVoiceSearchIcon[coi] != null) {
- updateVoiceSearchIcon(sVoiceSearchIcon[coi]);
- voiceVisible = true;
- }
- if (mSearchDropTargetBar != null) {
- mSearchDropTargetBar.onSearchPackagesChanged(searchVisible, voiceVisible);
- }
- }
-
private void checkForLocaleChange() {
if (sLocaleConfiguration == null) {
new AsyncTask<Void, Void, LocaleConfiguration>() {
@@ -620,7 +607,7 @@ public class Launcher extends Activity
private static void readConfiguration(Context context, LocaleConfiguration configuration) {
DataInputStream in = null;
try {
- in = new DataInputStream(context.openFileInput(PREFERENCES));
+ in = new DataInputStream(context.openFileInput(LauncherFiles.LAUNCHER_PREFERENCES));
configuration.locale = in.readUTF();
configuration.mcc = in.readInt();
configuration.mnc = in.readInt();
@@ -642,7 +629,8 @@ public class Launcher extends Activity
private static void writeConfiguration(Context context, LocaleConfiguration configuration) {
DataOutputStream out = null;
try {
- out = new DataOutputStream(context.openFileOutput(PREFERENCES, MODE_PRIVATE));
+ out = new DataOutputStream(context.openFileOutput(
+ LauncherFiles.LAUNCHER_PREFERENCES, MODE_PRIVATE));
out.writeUTF(configuration.locale);
out.writeInt(configuration.mcc);
out.writeInt(configuration.mnc);
@@ -651,7 +639,7 @@ public class Launcher extends Activity
// Ignore
} catch (IOException e) {
//noinspection ResultOfMethodCallIgnored
- context.getFileStreamPath(PREFERENCES).delete();
+ context.getFileStreamPath(LauncherFiles.LAUNCHER_PREFERENCES).delete();
} finally {
if (out != null) {
try {
@@ -749,8 +737,7 @@ public class Launcher extends Activity
return screenId;
}
- @Override
- protected void onActivityResult(
+ private void handleActivityResult(
final int requestCode, final int resultCode, final Intent data) {
// Reset the startActivity waiting flag
setWaitingForResult(false);
@@ -883,6 +870,16 @@ public class Launcher extends Activity
ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);
}
mDragLayer.clearAnimatedView();
+
+ }
+
+ @Override
+ protected void onActivityResult(
+ final int requestCode, final int resultCode, final Intent data) {
+ handleActivityResult(requestCode, resultCode, data);
+ if (mLauncherCallbacks != null) {
+ mLauncherCallbacks.onActivityResult(requestCode, resultCode, data);
+ }
}
private PendingAddArguments preparePendingAddArgs(int requestCode, Intent data, int
@@ -956,12 +953,20 @@ public class Launcher extends Activity
protected void onStop() {
super.onStop();
FirstFrameAnimatorHelper.setIsVisible(false);
+
+ if (mLauncherCallbacks != null) {
+ mLauncherCallbacks.onStop();
+ }
}
@Override
protected void onStart() {
super.onStart();
FirstFrameAnimatorHelper.setIsVisible(true);
+
+ if (mLauncherCallbacks != null) {
+ mLauncherCallbacks.onStart();
+ }
}
@Override
@@ -971,6 +976,11 @@ public class Launcher extends Activity
startTime = System.currentTimeMillis();
Log.v(TAG, "Launcher.onResume()");
}
+
+ if (mLauncherCallbacks != null) {
+ mLauncherCallbacks.preOnResume();
+ }
+
super.onResume();
// Restore the previous launcher state
@@ -1037,12 +1047,6 @@ public class Launcher extends Activity
// Process any items that were added while Launcher was away.
InstallShortcutReceiver.disableAndFlushInstallQueue(this);
- // Update the voice search button proxy
- updateVoiceButtonProxyVisible(false);
-
- // Again, as with the above scenario, it's possible that one or more of the global icons
- // were updated in the wrong orientation.
- updateGlobalIcons();
if (DEBUG_RESUME_TIME) {
Log.d(TAG, "Time spent in onResume: " + (System.currentTimeMillis() - startTime));
}
@@ -1059,6 +1063,10 @@ public class Launcher extends Activity
mWorkspace.onResume();
PackageInstallerCompat.getInstance(this).onResume();
+
+ if (mLauncherCallbacks != null) {
+ mLauncherCallbacks.onResume();
+ }
}
@Override
@@ -1077,25 +1085,10 @@ public class Launcher extends Activity
if (mWorkspace.getCustomContentCallbacks() != null) {
mWorkspace.getCustomContentCallbacks().onHide();
}
- }
-
- QSBScroller mQsbScroller = new QSBScroller() {
- int scrollY = 0;
-
- @Override
- public void setScrollY(int scroll) {
- scrollY = scroll;
- if (mWorkspace.isOnOrMovingToCustomContent()) {
- mSearchDropTargetBar.setTranslationY(- scrollY);
- getQsbBar().setTranslationY(-scrollY);
- }
+ if (mLauncherCallbacks != null) {
+ mLauncherCallbacks.onPause();
}
- };
-
- public void resetQSBScroll() {
- mSearchDropTargetBar.animate().translationY(0).start();
- getQsbBar().animate().translationY(0).start();
}
public interface CustomContentCallbacks {
@@ -1113,18 +1106,95 @@ public class Launcher extends Activity
boolean isScrollingAllowed();
}
+ public interface LauncherOverlay {
+
+ /**
+ * Touch interaction leading to overscroll has begun
+ */
+ public void onScrollInteractionBegin();
+
+ /**
+ * Touch interaction related to overscroll has ended
+ */
+ public void onScrollInteractionEnd();
+
+ /**
+ * Scroll progress, between 0 and 100, when the user scrolls beyond the leftmost
+ * screen (or in the case of RTL, the rightmost screen).
+ */
+ public void onScrollChange(int progress, boolean rtl);
+
+ /**
+ * Screen has stopped scrolling
+ */
+ public void onScrollSettled();
+
+ /**
+ * This method can be called by the Launcher in order to force the LauncherOverlay
+ * to exit fully immersive mode.
+ */
+ public void forceExitFullImmersion();
+ }
+
+ public interface LauncherOverlayCallbacks {
+ /**
+ * This method indicates whether a call to {@link #enterFullImmersion()} will succeed,
+ * however it doesn't modify any state within the launcher.
+ */
+ public boolean canEnterFullImmersion();
+
+ /**
+ * Should be called to tell Launcher that the LauncherOverlay will take over interaction,
+ * eg. by occupying the full screen and handling all touch events.
+ *
+ * @return true if Launcher allows the LauncherOverlay to become fully immersive. In this
+ * case, Launcher will modify any necessary state and assumes the overlay is
+ * handling all interaction. If false, the LauncherOverlay should cancel any
+ *
+ */
+ public boolean enterFullImmersion();
+
+ /**
+ * Must be called when exiting fully immersive mode. Indicates to Launcher that it has
+ * full control over UI and state.
+ */
+ public void exitFullImmersion();
+ }
+
+ class LauncherOverlayCallbacksImpl implements LauncherOverlayCallbacks {
+
+ @Override
+ public boolean canEnterFullImmersion() {
+ return mState == State.WORKSPACE;
+ }
+
+ @Override
+ public boolean enterFullImmersion() {
+ if (mState == State.WORKSPACE) {
+ // When fully immersed, disregard any touches which fall through.
+ mDragLayer.setBlockTouch(true);
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public void exitFullImmersion() {
+ mDragLayer.setBlockTouch(false);
+ }
+ }
+
protected boolean hasSettings() {
+ if (mLauncherCallbacks != null) {
+ return mLauncherCallbacks.hasSettings();
+ }
return false;
}
- public interface QSBScroller {
- public void setScrollY(int scrollY);
- }
- public QSBScroller addToCustomContentPage(View customContent,
+ public void addToCustomContentPage(View customContent,
CustomContentCallbacks callbacks, String description) {
mWorkspace.addToCustomContentPage(customContent, callbacks, description);
- return mQsbScroller;
}
// The custom content needs to offset its content to account for the QSB
@@ -1149,6 +1219,10 @@ public class Launcher extends Activity
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
mHasFocus = hasFocus;
+
+ if (mLauncherCallbacks != null) {
+ mLauncherCallbacks.onWindowFocusChanged(hasFocus);
+ }
}
private boolean acceptFilter() {
@@ -1335,9 +1409,6 @@ public class Launcher extends Activity
settingsButton.setOnTouchListener(getHapticFeedbackTouchListener());
} else {
settingsButton.setVisibility(View.GONE);
- FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) widgetButton.getLayoutParams();
- lp.gravity = Gravity.END | Gravity.TOP;
- widgetButton.requestLayout();
}
mOverviewPanel.setAlpha(0f);
@@ -1365,6 +1436,7 @@ public class Launcher extends Activity
dragController.addDropTarget(mWorkspace);
if (mSearchDropTargetBar != null) {
mSearchDropTargetBar.setup(this, dragController);
+ mSearchDropTargetBar.setQsbSearchBar(getQsbBar());
}
if (getResources().getBoolean(R.bool.debug_memory_enabled)) {
@@ -1437,7 +1509,7 @@ public class Launcher extends Activity
boolean foundCellSpan = false;
- ShortcutInfo info = mModel.infoFromShortcutIntent(this, data, null);
+ ShortcutInfo info = mModel.infoFromShortcutIntent(this, data);
if (info == null) {
return;
}
@@ -1887,8 +1959,11 @@ public class Launcher extends Activity
Folder openFolder = mWorkspace.getOpenFolder();
// In all these cases, only animate if we're already on home
mWorkspace.exitWidgetResizeMode();
+
+ boolean moveToDefaultScreen = mLauncherCallbacks != null ?
+ mLauncherCallbacks.shouldMoveToDefaultScreenOnHomeIntent() : true;
if (alreadyOnHome && mState == State.WORKSPACE && !mWorkspace.isTouchActive() &&
- openFolder == null && shouldMoveToDefaultScreenOnHomeIntent()) {
+ openFolder == null && moveToDefaultScreen) {
mWorkspace.moveToDefaultScreen(true);
}
@@ -1915,27 +1990,18 @@ public class Launcher extends Activity
mAppsCustomizeTabHost.reset();
}
- onHomeIntent();
+ if (mLauncherCallbacks != null) {
+ mLauncherCallbacks.onHomeIntent();
+ }
}
if (DEBUG_RESUME_TIME) {
Log.d(TAG, "Time spent in onNewIntent: " + (System.currentTimeMillis() - startTime));
}
- }
-
- /**
- * Override point for subclasses to prevent movement to the default screen when the home
- * button is pressed. Used (for example) in GEL, to prevent movement during a search.
- */
- protected boolean shouldMoveToDefaultScreenOnHomeIntent() {
- return true;
- }
- /**
- * Override point for subclasses to provide custom behaviour for when a home intent is fired.
- */
- protected void onHomeIntent() {
- // Do nothing
+ if (mLauncherCallbacks != null) {
+ mLauncherCallbacks.onNewIntent(intent);
+ }
}
@Override
@@ -1987,6 +2053,10 @@ public class Launcher extends Activity
outState.putInt("apps_customize_currentIndex", currentIndex);
}
outState.putSerializable(RUNTIME_STATE_VIEW_IDS, mItemIdToViewId);
+
+ if (mLauncherCallbacks != null) {
+ mLauncherCallbacks.onSaveInstanceState(outState);
+ }
}
@Override
@@ -2034,8 +2104,11 @@ public class Launcher extends Activity
mWorkspace = null;
mDragController = null;
- PackageInstallerCompat.getInstance(this).onStop();
LauncherAnimUtils.onDestroyActivity();
+
+ if (mLauncherCallbacks != null) {
+ mLauncherCallbacks.onDestroy();
+ }
}
public DragController getDragController() {
@@ -2089,6 +2162,11 @@ public class Launcher extends Activity
*/
public boolean startSearch(String initialQuery,
boolean selectInitialQuery, Bundle appSearchData, Rect sourceBounds) {
+ if (mLauncherCallbacks != null && mLauncherCallbacks.providesSearch()) {
+ return mLauncherCallbacks.startSearch(initialQuery, selectInitialQuery, appSearchData,
+ sourceBounds);
+ }
+
startGlobalSearch(initialQuery, selectInitialQuery,
appSearchData, sourceBounds);
return false;
@@ -2115,7 +2193,7 @@ public class Launcher extends Activity
} else {
appSearchData = new Bundle(appSearchData);
}
- // Set source to package name of app that starts global search, if not set already.
+ // Set source to package name of app that starts global search if not set already.
if (!appSearchData.containsKey("source")) {
appSearchData.putString("source", getPackageName());
}
@@ -2153,6 +2231,10 @@ public class Launcher extends Activity
showWorkspace(true);
}
}
+ if (mLauncherCallbacks != null) {
+ return mLauncherCallbacks.onPrepareOptionsMenu(menu);
+ }
+
return false;
}
@@ -2187,7 +2269,11 @@ public class Launcher extends Activity
}
}
- protected void onWorkspaceLockedChanged() { }
+ protected void onWorkspaceLockedChanged() {
+ if (mLauncherCallbacks != null) {
+ mLauncherCallbacks.onWorkspaceLockedChanged();
+ }
+ }
private void resetAddInfo() {
mPendingAddInfo.container = ItemInfo.NO_ID;
@@ -2349,6 +2435,9 @@ public class Launcher extends Activity
}
protected ComponentName getWallpaperPickerComponent() {
+ if (mLauncherCallbacks != null) {
+ return mLauncherCallbacks.getWallpaperPickerComponent();
+ }
return new ComponentName(getPackageName(), LauncherWallpaperPickerActivity.class.getName());
}
@@ -2369,7 +2458,7 @@ public class Launcher extends Activity
case KeyEvent.KEYCODE_HOME:
return true;
case KeyEvent.KEYCODE_VOLUME_DOWN:
- if (isPropertyEnabled(DUMP_STATE_PROPERTY)) {
+ if (Utilities.isPropertyEnabled(DUMP_STATE_PROPERTY)) {
dumpState();
return true;
}
@@ -2387,6 +2476,10 @@ public class Launcher extends Activity
@Override
public void onBackPressed() {
+ if (mLauncherCallbacks != null && mLauncherCallbacks.handleBackPressed()) {
+ return;
+ }
+
if (isAllAppsVisible()) {
if (mAppsCustomizeContent.getContentType() ==
AppsCustomizePagedView.ContentType.Applications) {
@@ -2469,6 +2562,9 @@ public class Launcher extends Activity
public void onClickPagedViewIcon(View v) {
startAppShortcutOrInfoActivity(v);
+ if (mLauncherCallbacks != null) {
+ mLauncherCallbacks.onClickPagedViewIcon(v);
+ }
}
public boolean onTouch(View v, MotionEvent event) {
@@ -2479,6 +2575,11 @@ public class Launcher extends Activity
* Event handler for the app widget view which has not fully restored.
*/
public void onClickPendingWidget(final PendingAppWidgetHostView v) {
+ if (mIsSafeModeEnabled) {
+ Toast.makeText(this, R.string.safemode_widget_error, Toast.LENGTH_SHORT).show();
+ return;
+ }
+
final LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) v.getTag();
if (v.isReadyForClickSetup()) {
int widgetId = info.appWidgetId;
@@ -2508,46 +2609,6 @@ public class Launcher extends Activity
}
/**
- * Event handler for the search button
- *
- * @param v The view that was clicked.
- */
- public void onClickSearchButton(View v) {
- v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
-
- onSearchRequested();
- }
-
- /**
- * Event handler for the voice button
- *
- * @param v The view that was clicked.
- */
- public void onClickVoiceButton(View v) {
- v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
-
- startVoice();
- }
-
- public void startVoice() {
- try {
- final SearchManager searchManager =
- (SearchManager) getSystemService(Context.SEARCH_SERVICE);
- ComponentName activityName = searchManager.getGlobalSearchActivity();
- Intent intent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- if (activityName != null) {
- intent.setPackage(activityName.getPackageName());
- }
- startActivity(null, intent, "onClickVoiceButton");
- } catch (ActivityNotFoundException e) {
- Intent intent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- startActivitySafely(null, intent, "onClickVoiceButton");
- }
- }
-
- /**
* Event handler for the "grid" button that appears on the home screen, which
* enters all apps mode.
*
@@ -2560,11 +2621,14 @@ public class Launcher extends Activity
} else {
showAllApps(true, AppsCustomizePagedView.ContentType.Applications, false);
}
+ if (mLauncherCallbacks != null) {
+ mLauncherCallbacks.onClickAllAppsButton(v);
+ }
}
private void showBrokenAppInstallDialog(final String packageName,
DialogInterface.OnClickListener onSearchClickListener) {
- new AlertDialog.Builder(new ContextThemeWrapper(this, android.R.style.Theme_DeviceDefault))
+ new AlertDialog.Builder(this)
.setTitle(R.string.abandoned_promises_title)
.setMessage(R.string.abandoned_promise_explanation)
.setPositiveButton(R.string.abandoned_search, onSearchClickListener)
@@ -2593,6 +2657,16 @@ public class Launcher extends Activity
// Open shortcut
final ShortcutInfo shortcut = (ShortcutInfo) tag;
+
+ if (shortcut.isDisabled != 0) {
+ int error = R.string.activity_not_available;
+ if ((shortcut.isDisabled & ShortcutInfo.FLAG_DISABLED_SAFEMODE) != 0) {
+ error = R.string.safemode_shortcut_error;
+ }
+ Toast.makeText(this, error, Toast.LENGTH_SHORT).show();
+ return;
+ }
+
final Intent intent = shortcut.intent;
// Check for special shortcuts
@@ -2624,6 +2698,10 @@ public class Launcher extends Activity
// Start activities
startAppShortcutOrInfoActivity(v);
+
+ if (mLauncherCallbacks != null) {
+ mLauncherCallbacks.onClickAppShortcut(v);
+ }
}
private void startAppShortcutOrInfoActivity(View v) {
@@ -2697,6 +2775,10 @@ public class Launcher extends Activity
}
}
}
+
+ if (mLauncherCallbacks != null) {
+ mLauncherCallbacks.onClickFolderIcon(v);
+ }
}
/**
@@ -2705,7 +2787,14 @@ public class Launcher extends Activity
*/
protected void onClickAddWidgetButton(View view) {
if (LOGD) Log.d(TAG, "onClickAddWidgetButton");
- showAllApps(true, AppsCustomizePagedView.ContentType.Widgets, true);
+ if (mIsSafeModeEnabled) {
+ Toast.makeText(this, R.string.safemode_widget_error, Toast.LENGTH_SHORT).show();
+ } else {
+ showAllApps(true, AppsCustomizePagedView.ContentType.Widgets, true);
+ if (mLauncherCallbacks != null) {
+ mLauncherCallbacks.onClickAddWidgetButton(view);
+ }
+ }
}
/**
@@ -2717,6 +2806,10 @@ public class Launcher extends Activity
final Intent pickWallpaper = new Intent(Intent.ACTION_SET_WALLPAPER);
pickWallpaper.setComponent(getWallpaperPickerComponent());
startActivityForResult(pickWallpaper, REQUEST_PICK_WALLPAPER);
+
+ if (mLauncherCallbacks != null) {
+ mLauncherCallbacks.onClickWallpaperPicker(v);
+ }
}
/**
@@ -2725,6 +2818,9 @@ public class Launcher extends Activity
*/
protected void onClickSettingsButton(View v) {
if (LOGD) Log.d(TAG, "onClickSettingsButton");
+ if (mLauncherCallbacks != null) {
+ mLauncherCallbacks.onClickSettingsButton(v);
+ }
}
public void onTouchDownAllAppsButton(View v) {
@@ -2752,13 +2848,27 @@ public class Launcher extends Activity
return mHapticFeedbackTouchListener;
}
- public void onDragStarted(View view) {}
+ public void onDragStarted(View view) {
+ if (isOnCustomContent()) {
+ // Custom content screen doesn't participate in drag and drop. If on custom
+ // content screen, move to default.
+ moveWorkspaceToDefaultScreen();
+ }
+
+ if (mLauncherCallbacks != null) {
+ mLauncherCallbacks.onDragStarted(view);
+ }
+ }
/**
* Called when the user stops interacting with the launcher.
* This implies that the user is now on the homescreen and is not doing housekeeping.
*/
- protected void onInteractionEnd() {}
+ protected void onInteractionEnd() {
+ if (mLauncherCallbacks != null) {
+ mLauncherCallbacks.onInteractionEnd();
+ }
+ }
/**
* Called when the user starts interacting with the launcher.
@@ -2769,13 +2879,15 @@ public class Launcher extends Activity
* This is a good time to stop doing things that only make sense
* when the user is on the homescreen and not doing housekeeping.
*/
- protected void onInteractionBegin() {}
+ protected void onInteractionBegin() {
+ if (mLauncherCallbacks != null) {
+ mLauncherCallbacks.onInteractionBegin();
+ }
+ }
void startApplicationDetailsActivity(ComponentName componentName, UserHandleCompat user) {
- String packageName = componentName.getPackageName();
try {
LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);
- UserManagerCompat userManager = UserManagerCompat.getInstance(this);
launcherApps.showAppDetailsForProfile(componentName, user);
} catch (SecurityException e) {
Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
@@ -3250,8 +3362,6 @@ public class Launcher extends Activity
final View page = content.getPageAt(content.getCurrentPage());
final View revealView = toView.findViewById(R.id.fake_page);
- final float initialPanelAlpha = 1f;
-
final boolean isWidgetTray = contentType == AppsCustomizePagedView.ContentType.Widgets;
if (isWidgetTray) {
revealView.setBackground(res.getDrawable(R.drawable.quantum_panel_dark));
@@ -3374,6 +3484,9 @@ public class Launcher extends Activity
if (mSearchDropTargetBar != null) {
mSearchDropTargetBar.hideSearchBar(false);
}
+
+ // This can hold unnecessary references to views.
+ mStateAnimation = null;
}
});
@@ -3399,11 +3512,7 @@ public class Launcher extends Activity
for (int i = 0; i < layerViews.size(); i++) {
View v = layerViews.get(i);
if (v != null) {
- boolean attached = true;
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
- attached = v.isAttachedToWindow();
- }
- if (attached) v.buildLayer();
+ if (Utilities.isViewAttachedToWindow(v)) v.buildLayer();
}
}
}
@@ -3532,14 +3641,14 @@ public class Launcher extends Activity
yDrift = isWidgetTray ? height / 2 : allAppsToPanelDelta[1];
xDrift = isWidgetTray ? 0 : allAppsToPanelDelta[0];
} else {
- yDrift = 5 * height / 4;
+ yDrift = 2 * height / 3;
xDrift = 0;
}
revealView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
TimeInterpolator decelerateInterpolator = material ?
new LogDecelerateInterpolator(100, 0) :
- new LogDecelerateInterpolator(30, 0);
+ new DecelerateInterpolator(1f);
// The vertical motion of the apps panel should be delayed by one frame
// from the conceal animation in order to give the right feel. We correpsondingly
@@ -3563,9 +3672,9 @@ public class Launcher extends Activity
revealView.setAlpha(1f);
ObjectAnimator panelAlpha = LauncherAnimUtils.ofFloat(revealView, "alpha",
1f, finalAlpha);
- panelAlpha.setDuration(revealDuration);
- panelAlpha.setInterpolator(material ? decelerateInterpolator :
- new AccelerateInterpolator(1.5f));
+ panelAlpha.setDuration(material ? revealDuration : 150);
+ panelAlpha.setInterpolator(decelerateInterpolator);
+ panelAlpha.setStartDelay(material ? 0 : itemsAlphaStagger + SINGLE_FRAME_DELAY);
mStateAnimation.play(panelAlpha);
}
@@ -3659,6 +3768,9 @@ public class Launcher extends Activity
content.setCurrentPage(content.getNextPage());
mAppsCustomizeContent.updateCurrentPageScroll();
+
+ // This can hold unnecessary references to views.
+ mStateAnimation = null;
}
});
@@ -3676,11 +3788,7 @@ public class Launcher extends Activity
for (int i = 0; i < layerViews.size(); i++) {
View v = layerViews.get(i);
if (v != null) {
- boolean attached = true;
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
- attached = v.isAttachedToWindow();
- }
- if (attached) v.buildLayer();
+ if (Utilities.isViewAttachedToWindow(v)) v.buildLayer();
}
}
}
@@ -3702,8 +3810,15 @@ public class Launcher extends Activity
@Override
public void onTrimMemory(int level) {
super.onTrimMemory(level);
- if (level >= ComponentCallbacks2.TRIM_MEMORY_MODERATE) {
- mAppsCustomizeTabHost.onTrimMemory();
+ if (level >= ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {
+ // The widget preview db can result in holding onto over
+ // 3MB of memory for caching which isn't necessary.
+ SQLiteDatabase.releaseMemory();
+
+ // This clears all widget bitmaps from the widget tray
+ if (mAppsCustomizeTabHost != null) {
+ mAppsCustomizeTabHost.trimMemory();
+ }
}
}
@@ -3831,258 +3946,62 @@ public class Launcher extends Activity
// TODO
}
- /**
- * Hides the hotseat area.
- */
- void hideHotseat(boolean animated) {
- if (!LauncherAppState.getInstance().isScreenLarge()) {
- if (animated) {
- if (mHotseat.getAlpha() != 0f) {
- int duration = 0;
- if (mSearchDropTargetBar != null) {
- duration = mSearchDropTargetBar.getTransitionOutDuration();
- }
- mHotseat.animate().alpha(0f).setDuration(duration);
- }
- } else {
- mHotseat.setAlpha(0f);
- }
- }
- }
-
- /**
- * Add an item from all apps or customize onto the given workspace screen.
- * If layout is null, add to the current screen.
- */
- void addExternalItemToScreen(ItemInfo itemInfo, final CellLayout layout) {
- if (!mWorkspace.addExternalItemToScreen(itemInfo, layout)) {
- showOutOfSpaceMessage(isHotseatLayout(layout));
- }
- }
-
- /** Maps the current orientation to an index for referencing orientation correct global icons */
- private int getCurrentOrientationIndexForGlobalIcons() {
- // default - 0, landscape - 1
- switch (getResources().getConfiguration().orientation) {
- case Configuration.ORIENTATION_LANDSCAPE:
- return 1;
- default:
- return 0;
- }
- }
-
- private Drawable getExternalPackageToolbarIcon(ComponentName activityName, String resourceName) {
- try {
- PackageManager packageManager = getPackageManager();
- // Look for the toolbar icon specified in the activity meta-data
- Bundle metaData = packageManager.getActivityInfo(
- activityName, PackageManager.GET_META_DATA).metaData;
- if (metaData != null) {
- int iconResId = metaData.getInt(resourceName);
- if (iconResId != 0) {
- Resources res = packageManager.getResourcesForActivity(activityName);
- return res.getDrawable(iconResId);
- }
- }
- } catch (NameNotFoundException e) {
- // This can happen if the activity defines an invalid drawable
- Log.w(TAG, "Failed to load toolbar icon; " + activityName.flattenToShortString() +
- " not found", e);
- } catch (Resources.NotFoundException nfe) {
- // This can happen if the activity defines an invalid drawable
- Log.w(TAG, "Failed to load toolbar icon from " + activityName.flattenToShortString(),
- nfe);
- }
- return null;
- }
-
- // if successful in getting icon, return it; otherwise, set button to use default drawable
- private Drawable.ConstantState updateTextButtonWithIconFromExternalActivity(
- int buttonId, ComponentName activityName, int fallbackDrawableId,
- String toolbarResourceName) {
- Drawable toolbarIcon = getExternalPackageToolbarIcon(activityName, toolbarResourceName);
- Resources r = getResources();
- int w = r.getDimensionPixelSize(R.dimen.toolbar_external_icon_width);
- int h = r.getDimensionPixelSize(R.dimen.toolbar_external_icon_height);
-
- TextView button = (TextView) findViewById(buttonId);
- // If we were unable to find the icon via the meta-data, use a generic one
- if (toolbarIcon == null) {
- toolbarIcon = r.getDrawable(fallbackDrawableId);
- toolbarIcon.setBounds(0, 0, w, h);
- if (button != null) {
- button.setCompoundDrawables(toolbarIcon, null, null, null);
- }
- return null;
- } else {
- toolbarIcon.setBounds(0, 0, w, h);
- if (button != null) {
- button.setCompoundDrawables(toolbarIcon, null, null, null);
- }
- return toolbarIcon.getConstantState();
- }
- }
-
- // if successful in getting icon, return it; otherwise, set button to use default drawable
- private Drawable.ConstantState updateButtonWithIconFromExternalActivity(
- int buttonId, ComponentName activityName, int fallbackDrawableId,
- String toolbarResourceName) {
- ImageView button = (ImageView) findViewById(buttonId);
- Drawable toolbarIcon = getExternalPackageToolbarIcon(activityName, toolbarResourceName);
-
- if (button != null) {
- // If we were unable to find the icon via the meta-data, use a
- // generic one
- if (toolbarIcon == null) {
- button.setImageResource(fallbackDrawableId);
- } else {
- button.setImageDrawable(toolbarIcon);
- }
- }
-
- return toolbarIcon != null ? toolbarIcon.getConstantState() : null;
-
- }
-
- private void updateTextButtonWithDrawable(int buttonId, Drawable d) {
- TextView button = (TextView) findViewById(buttonId);
- button.setCompoundDrawables(d, null, null, null);
- }
-
- private void updateButtonWithDrawable(int buttonId, Drawable.ConstantState d) {
- ImageView button = (ImageView) findViewById(buttonId);
- button.setImageDrawable(d.newDrawable(getResources()));
- }
-
- private void invalidatePressedFocusedStates(View container, View button) {
- if (container instanceof HolographicLinearLayout) {
- HolographicLinearLayout layout = (HolographicLinearLayout) container;
- layout.invalidatePressedFocusedStates();
- } else if (button instanceof HolographicImageView) {
- HolographicImageView view = (HolographicImageView) button;
- view.invalidatePressedFocusedStates();
- }
+ protected void disableVoiceButtonProxy(boolean disable) {
+ // NO-OP
}
public View getQsbBar() {
- if (mQsb == null) {
- mQsb = mInflater.inflate(R.layout.qsb, mSearchDropTargetBar, false);
- mSearchDropTargetBar.addView(mQsb);
+ if (mLauncherCallbacks != null && mLauncherCallbacks.providesSearch()) {
+ return mLauncherCallbacks.getQsbBar();
}
- return mQsb;
- }
-
- protected boolean updateGlobalSearchIcon() {
- final View searchButtonContainer = findViewById(R.id.search_button_container);
- final ImageView searchButton = (ImageView) findViewById(R.id.search_button);
- final View voiceButtonContainer = findViewById(R.id.voice_button_container);
- final View voiceButton = findViewById(R.id.voice_button);
- final SearchManager searchManager =
- (SearchManager) getSystemService(Context.SEARCH_SERVICE);
- ComponentName activityName = searchManager.getGlobalSearchActivity();
- if (activityName != null) {
- int coi = getCurrentOrientationIndexForGlobalIcons();
- sGlobalSearchIcon[coi] = updateButtonWithIconFromExternalActivity(
- R.id.search_button, activityName, R.drawable.ic_home_search_normal_holo,
- TOOLBAR_SEARCH_ICON_METADATA_NAME);
- if (sGlobalSearchIcon[coi] == null) {
- sGlobalSearchIcon[coi] = updateButtonWithIconFromExternalActivity(
- R.id.search_button, activityName, R.drawable.ic_home_search_normal_holo,
- TOOLBAR_ICON_METADATA_NAME);
+ if (mQsb == null) {
+ AppWidgetProviderInfo searchProvider = Utilities.getSearchWidgetProvider(this);
+ if (searchProvider == null) {
+ return null;
}
- if (searchButtonContainer != null) searchButtonContainer.setVisibility(View.VISIBLE);
- searchButton.setVisibility(View.VISIBLE);
- invalidatePressedFocusedStates(searchButtonContainer, searchButton);
- return true;
- } else {
- // We disable both search and voice search when there is no global search provider
- if (searchButtonContainer != null) searchButtonContainer.setVisibility(View.GONE);
- if (voiceButtonContainer != null) voiceButtonContainer.setVisibility(View.GONE);
- if (searchButton != null) searchButton.setVisibility(View.GONE);
- if (voiceButton != null) voiceButton.setVisibility(View.GONE);
- updateVoiceButtonProxyVisible(false);
- return false;
- }
- }
-
- protected void updateGlobalSearchIcon(Drawable.ConstantState d) {
- final View searchButtonContainer = findViewById(R.id.search_button_container);
- final View searchButton = (ImageView) findViewById(R.id.search_button);
- updateButtonWithDrawable(R.id.search_button, d);
- invalidatePressedFocusedStates(searchButtonContainer, searchButton);
- }
+ Bundle opts = new Bundle();
+ opts.putInt(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY,
+ AppWidgetProviderInfo.WIDGET_CATEGORY_SEARCHBOX);
+
+ SharedPreferences sp = getSharedPreferences(
+ LauncherAppState.getSharedPreferencesKey(), MODE_PRIVATE);
+ int widgetId = sp.getInt(QSB_WIDGET_ID, -1);
+ AppWidgetProviderInfo widgetInfo = mAppWidgetManager.getAppWidgetInfo(widgetId);
+ if (!searchProvider.provider.flattenToString().equals(
+ sp.getString(QSB_WIDGET_PROVIDER, null))
+ || (widgetInfo == null)
+ || !widgetInfo.provider.equals(searchProvider.provider)) {
+ // A valid widget is not already bound.
+ if (widgetId > -1) {
+ mAppWidgetHost.deleteAppWidgetId(widgetId);
+ widgetId = -1;
+ }
- protected boolean updateVoiceSearchIcon(boolean searchVisible) {
- final View voiceButtonContainer = findViewById(R.id.voice_button_container);
- final View voiceButton = findViewById(R.id.voice_button);
+ // Try to bind a new widget
+ widgetId = mAppWidgetHost.allocateAppWidgetId();
- // We only show/update the voice search icon if the search icon is enabled as well
- final SearchManager searchManager =
- (SearchManager) getSystemService(Context.SEARCH_SERVICE);
- ComponentName globalSearchActivity = searchManager.getGlobalSearchActivity();
+ if (!AppWidgetManagerCompat.getInstance(this)
+ .bindAppWidgetIdIfAllowed(widgetId, searchProvider, opts)) {
+ mAppWidgetHost.deleteAppWidgetId(widgetId);
+ widgetId = -1;
+ }
- ComponentName activityName = null;
- if (globalSearchActivity != null) {
- // Check if the global search activity handles voice search
- Intent intent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);
- intent.setPackage(globalSearchActivity.getPackageName());
- activityName = intent.resolveActivity(getPackageManager());
- }
-
- if (activityName == null) {
- // Fallback: check if an activity other than the global search activity
- // resolves this
- Intent intent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);
- activityName = intent.resolveActivity(getPackageManager());
- }
- if (searchVisible && activityName != null) {
- int coi = getCurrentOrientationIndexForGlobalIcons();
- sVoiceSearchIcon[coi] = updateButtonWithIconFromExternalActivity(
- R.id.voice_button, activityName, R.drawable.ic_home_voice_search_holo,
- TOOLBAR_VOICE_SEARCH_ICON_METADATA_NAME);
- if (sVoiceSearchIcon[coi] == null) {
- sVoiceSearchIcon[coi] = updateButtonWithIconFromExternalActivity(
- R.id.voice_button, activityName, R.drawable.ic_home_voice_search_holo,
- TOOLBAR_ICON_METADATA_NAME);
+ sp.edit()
+ .putInt(QSB_WIDGET_ID, widgetId)
+ .putString(QSB_WIDGET_PROVIDER, searchProvider.provider.flattenToString())
+ .commit();
}
- if (voiceButtonContainer != null) voiceButtonContainer.setVisibility(View.VISIBLE);
- voiceButton.setVisibility(View.VISIBLE);
- updateVoiceButtonProxyVisible(false);
- invalidatePressedFocusedStates(voiceButtonContainer, voiceButton);
- return true;
- } else {
- if (voiceButtonContainer != null) voiceButtonContainer.setVisibility(View.GONE);
- if (voiceButton != null) voiceButton.setVisibility(View.GONE);
- updateVoiceButtonProxyVisible(false);
- return false;
- }
- }
- protected void updateVoiceSearchIcon(Drawable.ConstantState d) {
- final View voiceButtonContainer = findViewById(R.id.voice_button_container);
- final View voiceButton = findViewById(R.id.voice_button);
- updateButtonWithDrawable(R.id.voice_button, d);
- invalidatePressedFocusedStates(voiceButtonContainer, voiceButton);
- }
-
- public void updateVoiceButtonProxyVisible(boolean forceDisableVoiceButtonProxy) {
- final View voiceButtonProxy = findViewById(R.id.voice_button_proxy);
- if (voiceButtonProxy != null) {
- boolean visible = !forceDisableVoiceButtonProxy &&
- mWorkspace.shouldVoiceButtonProxyBeVisible();
- voiceButtonProxy.setVisibility(visible ? View.VISIBLE : View.GONE);
- voiceButtonProxy.bringToFront();
+ if (widgetId != -1) {
+ mQsb = mAppWidgetHost.createView(this, widgetId, searchProvider);
+ mQsb.updateAppWidgetOptions(opts);
+ mQsb.setPadding(0, 0, 0, 0);
+ mSearchDropTargetBar.addView(mQsb);
+ }
}
- }
-
- /**
- * This is an overrid eot disable the voice button proxy. If disabled is true, then the voice button proxy
- * will be hidden regardless of what shouldVoiceButtonProxyBeVisible() returns.
- */
- public void disableVoiceButtonProxy(boolean disabled) {
- updateVoiceButtonProxyVisible(disabled);
+ return mQsb;
}
@Override
@@ -4455,8 +4374,9 @@ public class Launcher extends Activity
final Workspace workspace = mWorkspace;
AppWidgetProviderInfo appWidgetInfo;
- if (((item.restoreStatus & LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY) == 0) &&
- ((item.restoreStatus & LauncherAppWidgetInfo.FLAG_ID_NOT_VALID) != 0)) {
+ if (!mIsSafeModeEnabled
+ && ((item.restoreStatus & LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY) == 0)
+ && ((item.restoreStatus & LauncherAppWidgetInfo.FLAG_ID_NOT_VALID) != 0)) {
appWidgetInfo = mModel.findAppWidgetProviderInfoWithComponent(this, item.providerName);
if (appWidgetInfo == null) {
@@ -4506,7 +4426,7 @@ public class Launcher extends Activity
LauncherModel.updateItemInDatabase(this, item);
}
- if (item.restoreStatus == LauncherAppWidgetInfo.RESTORE_COMPLETED) {
+ if (!mIsSafeModeEnabled && item.restoreStatus == LauncherAppWidgetInfo.RESTORE_COMPLETED) {
final int appWidgetId = item.appWidgetId;
appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appWidgetId);
if (DEBUG_WIDGETS) {
@@ -4516,7 +4436,8 @@ public class Launcher extends Activity
item.hostView = mAppWidgetHost.createView(this, appWidgetId, appWidgetInfo);
} else {
appWidgetInfo = null;
- PendingAppWidgetHostView view = new PendingAppWidgetHostView(this, item);
+ PendingAppWidgetHostView view = new PendingAppWidgetHostView(this, item,
+ mIsSafeModeEnabled);
view.updateIcon(mIconCache);
item.hostView = view;
item.hostView.updateAppWidget(null);
@@ -4610,7 +4531,10 @@ public class Launcher extends Activity
mIntentsOnWorkspaceFromUpgradePath = mWorkspace.getUniqueComponents(true, null);
}
PackageInstallerCompat.getInstance(this).onFinishBind();
- mModel.recheckRestoredItems(this);
+
+ if (mLauncherCallbacks != null) {
+ mLauncherCallbacks.finishBindingItems(upgradePath);
+ }
}
private void sendLoadingCompleteBroadcastIfNecessary() {
@@ -4658,13 +4582,15 @@ public class Launcher extends Activity
getDeviceProfile().getSearchBarBounds();
}
- @Override
public void bindSearchablesChanged() {
- boolean searchVisible = updateGlobalSearchIcon();
- boolean voiceVisible = updateVoiceSearchIcon(searchVisible);
- if (mSearchDropTargetBar != null) {
- mSearchDropTargetBar.onSearchPackagesChanged(searchVisible, voiceVisible);
+ if (mSearchDropTargetBar == null) {
+ return;
}
+ if (mQsb != null) {
+ mSearchDropTargetBar.removeView(mQsb);
+ mQsb = null;
+ }
+ mSearchDropTargetBar.setQsbSearchBar(getQsbBar());
}
/**
@@ -4692,6 +4618,9 @@ public class Launcher extends Activity
LauncherModel.getSortedWidgetsAndShortcuts(this));
}
}
+ if (mLauncherCallbacks != null) {
+ mLauncherCallbacks.bindAllApplications(apps);
+ }
}
/**
@@ -4709,31 +4638,54 @@ public class Launcher extends Activity
return;
}
- if (mWorkspace != null) {
- mWorkspace.updateShortcutsAndWidgets(apps);
- }
-
if (!LauncherAppState.isDisableAllApps() &&
mAppsCustomizeContent != null) {
mAppsCustomizeContent.updateApps(apps);
}
}
+ @Override
+ public void bindWidgetsRestored(final ArrayList<LauncherAppWidgetInfo> widgets) {
+ Runnable r = new Runnable() {
+ public void run() {
+ bindWidgetsRestored(widgets);
+ }
+ };
+ if (waitUntilResume(r)) {
+ return;
+ }
+ mWorkspace.widgetsRestored(widgets);
+ }
+
/**
- * Packages were restored
+ * Some shortcuts were updated in the background.
+ *
+ * Implementation of the method from LauncherModel.Callbacks.
*/
- public void bindAppsRestored(final ArrayList<AppInfo> apps) {
+ @Override
+ public void bindShortcutsChanged(final ArrayList<ShortcutInfo> updated,
+ final ArrayList<ShortcutInfo> removed, final UserHandleCompat user) {
Runnable r = new Runnable() {
public void run() {
- bindAppsRestored(apps);
+ bindShortcutsChanged(updated, removed, user);
}
};
if (waitUntilResume(r)) {
return;
}
- if (mWorkspace != null) {
- mWorkspace.updateShortcutsAndWidgets(apps);
+ if (!updated.isEmpty()) {
+ mWorkspace.updateShortcuts(updated);
+ }
+
+ if (!removed.isEmpty()) {
+ HashSet<ComponentName> removedComponents = new HashSet<ComponentName>();
+ for (ShortcutInfo si : removed) {
+ removedComponents.add(si.getTargetComponent());
+ }
+ mWorkspace.removeItemsByComponentName(removedComponents, user);
+ // Notify the drag controller
+ mDragController.onAppsRemoved(new ArrayList<String>(), removedComponents);
}
}
@@ -4768,28 +4720,38 @@ public class Launcher extends Activity
* we only remove specific components from the workspace, where as
* package-removal should clear all items by package name.
*
+ * @param reason if non-zero, the icons are not permanently removed, rather marked as disabled.
* Implementation of the method from LauncherModel.Callbacks.
*/
+ @Override
public void bindComponentsRemoved(final ArrayList<String> packageNames,
- final ArrayList<AppInfo> appInfos, final UserHandleCompat user) {
+ final ArrayList<AppInfo> appInfos, final UserHandleCompat user, final int reason) {
Runnable r = new Runnable() {
public void run() {
- bindComponentsRemoved(packageNames, appInfos, user);
+ bindComponentsRemoved(packageNames, appInfos, user, reason);
}
};
if (waitUntilResume(r)) {
return;
}
- if (!packageNames.isEmpty()) {
- mWorkspace.removeItemsByPackageName(packageNames, user);
- }
- if (!appInfos.isEmpty()) {
- mWorkspace.removeItemsByApplicationInfo(appInfos, user);
- }
+ if (reason == 0) {
+ HashSet<ComponentName> removedComponents = new HashSet<ComponentName>();
+ for (AppInfo info : appInfos) {
+ removedComponents.add(info.componentName);
+ }
+ if (!packageNames.isEmpty()) {
+ mWorkspace.removeItemsByPackageName(packageNames, user);
+ }
+ if (!removedComponents.isEmpty()) {
+ mWorkspace.removeItemsByComponentName(removedComponents, user);
+ }
+ // Notify the drag controller
+ mDragController.onAppsRemoved(packageNames, removedComponents);
- // Notify the drag controller
- mDragController.onAppsRemoved(packageNames, appInfos);
+ } else {
+ mWorkspace.disableShortcutsByPackageName(packageNames, user, reason);
+ }
// Update AllApps
if (!LauncherAppState.isDisableAllApps() &&
@@ -4852,19 +4814,14 @@ public class Launcher extends Activity
return oriMap[(d.getRotation() + indexOffset) % 4];
}
- public boolean isRotationEnabled() {
- boolean enableRotation = sForceEnableRotation ||
- getResources().getBoolean(R.bool.allow_rotation);
- return enableRotation;
- }
public void lockScreenOrientation() {
- if (isRotationEnabled()) {
+ if (Utilities.isRotationEnabled(this)) {
setRequestedOrientation(mapConfigurationOriActivityInfoOri(getResources()
.getConfiguration().orientation));
}
}
public void unlockScreenOrientation(boolean immediate) {
- if (isRotationEnabled()) {
+ if (Utilities.isRotationEnabled(this)) {
if (immediate) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
} else {
@@ -4877,16 +4834,10 @@ public class Launcher extends Activity
}
}
- /**
- * Called when the SearchBar hint should be changed.
- *
- * @param hint the hint to be displayed in the search bar.
- */
- protected void onSearchBarHintChanged(String hint) {
-
- }
-
protected boolean isLauncherPreinstalled() {
+ if (mLauncherCallbacks != null) {
+ return mLauncherCallbacks.isLauncherPreinstalled();
+ }
PackageManager pm = getPackageManager();
try {
ApplicationInfo ai = pm.getApplicationInfo(getComponentName().getPackageName(), 0);
@@ -4906,39 +4857,20 @@ public class Launcher extends Activity
* when our wallpaper cropper was not yet used to set a wallpaper.
*/
protected boolean overrideWallpaperDimensions() {
+ if (mLauncherCallbacks != null) {
+ return mLauncherCallbacks.overrideWallpaperDimensions();
+ }
return true;
}
- protected boolean shouldClingFocusHotseatApp() {
- return false;
- }
- protected String getFirstRunClingSearchBarHint() {
- return "";
- }
- protected String getFirstRunCustomContentHint() {
- return "";
- }
- protected int getFirstRunFocusedHotseatAppDrawableId() {
- return -1;
- }
- protected ComponentName getFirstRunFocusedHotseatAppComponentName() {
- return null;
- }
- protected int getFirstRunFocusedHotseatAppRank() {
- return -1;
- }
- protected String getFirstRunFocusedHotseatAppBubbleTitle() {
- return "";
- }
- protected String getFirstRunFocusedHotseatAppBubbleDescription() {
- return "";
- }
-
/**
* To be overridden by subclasses to indicate that there is an activity to launch
* before showing the standard launcher experience.
*/
protected boolean hasFirstRunActivity() {
+ if (mLauncherCallbacks != null) {
+ return mLauncherCallbacks.hasFirstRunActivity();
+ }
return false;
}
@@ -4946,6 +4878,9 @@ public class Launcher extends Activity
* To be overridden by subclasses to launch any first run activity
*/
protected Intent getFirstRunActivity() {
+ if (mLauncherCallbacks != null) {
+ return mLauncherCallbacks.getFirstRunActivity();
+ }
return null;
}
@@ -4982,6 +4917,9 @@ public class Launcher extends Activity
* screen that must be displayed and dismissed.
*/
protected boolean hasDismissableIntroScreen() {
+ if (mLauncherCallbacks != null) {
+ return mLauncherCallbacks.hasDismissableIntroScreen();
+ }
return false;
}
@@ -4989,6 +4927,9 @@ public class Launcher extends Activity
* Full screen intro screen to be shown and dismissed before the launcher can be used.
*/
protected View getIntroScreen() {
+ if (mLauncherCallbacks != null) {
+ return mLauncherCallbacks.getIntroScreen();
+ }
return null;
}
@@ -5007,6 +4948,9 @@ public class Launcher extends Activity
if (introScreen != null) {
mDragLayer.showOverlayView(introScreen);
}
+ if (mLauncherOverlayContainer != null) {
+ mLauncherOverlayContainer.setVisibility(View.INVISIBLE);
+ }
}
public void dismissIntroScreen() {
@@ -5018,11 +4962,17 @@ public class Launcher extends Activity
@Override
public void run() {
mDragLayer.dismissOverlayView();
+ if (mLauncherOverlayContainer != null) {
+ mLauncherOverlayContainer.setVisibility(View.VISIBLE);
+ }
showFirstRunClings();
}
}, ACTIVITY_START_DELAY);
} else {
mDragLayer.dismissOverlayView();
+ if (mLauncherOverlayContainer != null) {
+ mLauncherOverlayContainer.setVisibility(View.VISIBLE);
+ }
showFirstRunClings();
}
changeWallpaperVisiblity(true);
@@ -5100,6 +5050,9 @@ public class Launcher extends Activity
@Override
public void onPageSwitch(View newPage, int newPageIndex) {
+ if (mLauncherCallbacks != null) {
+ mLauncherCallbacks.onPageSwitch(newPage, newPageIndex);
+ }
}
/**
@@ -5131,6 +5084,9 @@ public class Launcher extends Activity
writer.println(" " + sDumpLogs.get(i));
}
}
+ if (mLauncherCallbacks != null) {
+ mLauncherCallbacks.dump(prefix, fd, writer, args);
+ }
}
public static void dumpDebugLogsToConsole() {
diff --git a/src/com/android/launcher3/LauncherAppState.java b/src/com/android/launcher3/LauncherAppState.java
index 246278fa2..b7c45a340 100644
--- a/src/com/android/launcher3/LauncherAppState.java
+++ b/src/com/android/launcher3/LauncherAppState.java
@@ -16,6 +16,7 @@
package com.android.launcher3;
+import android.annotation.TargetApi;
import android.app.SearchManager;
import android.content.ComponentName;
import android.content.ContentResolver;
@@ -25,29 +26,34 @@ import android.content.IntentFilter;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.database.ContentObserver;
+import android.graphics.Point;
+import android.os.Build;
import android.os.Handler;
+import android.util.DisplayMetrics;
import android.util.Log;
-
+import android.view.Display;
+import android.view.WindowManager;
import com.android.launcher3.compat.LauncherAppsCompat;
+import com.android.launcher3.compat.PackageInstallerCompat;
import com.android.launcher3.compat.PackageInstallerCompat.PackageInstallInfo;
-
import java.lang.ref.WeakReference;
import java.util.ArrayList;
public class LauncherAppState implements DeviceProfile.DeviceProfileCallbacks {
private static final String TAG = "LauncherAppState";
- private static final String SHARED_PREFERENCES_KEY = "com.android.launcher3.prefs";
private static final boolean DEBUG = false;
private final AppFilter mAppFilter;
private final BuildInfo mBuildInfo;
- private LauncherModel mModel;
- private IconCache mIconCache;
+ private final LauncherModel mModel;
+ private final IconCache mIconCache;
+
+ private final boolean mIsScreenLarge;
+ private final float mScreenDensity;
+ private final int mLongPressTimeout = 300;
+
private WidgetPreviewLoader.CacheDb mWidgetPreviewCacheDb;
- private boolean mIsScreenLarge;
- private float mScreenDensity;
- private int mLongPressTimeout = 300;
private boolean mWallpaperChangedSinceLastCheck;
private static WeakReference<LauncherProvider> sLauncherProvider;
@@ -135,6 +141,7 @@ public class LauncherAppState implements DeviceProfile.DeviceProfileCallbacks {
sContext.unregisterReceiver(mModel);
final LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(sContext);
launcherApps.removeOnAppsChangedCallback(mModel);
+ PackageInstallerCompat.getInstance(sContext).onStop();
ContentResolver resolver = sContext.getContentResolver();
resolver.unregisterContentObserver(mFavoritesObserver);
@@ -154,9 +161,6 @@ public class LauncherAppState implements DeviceProfile.DeviceProfileCallbacks {
};
LauncherModel setLauncher(Launcher launcher) {
- if (mModel == null) {
- throw new IllegalStateException("setLauncher() called before init()");
- }
mModel.initialize(launcher);
return mModel;
}
@@ -186,26 +190,48 @@ public class LauncherAppState implements DeviceProfile.DeviceProfileCallbacks {
}
public static String getSharedPreferencesKey() {
- return SHARED_PREFERENCES_KEY;
+ return LauncherFiles.SHARED_PREFERENCES_KEY;
}
- DeviceProfile initDynamicGrid(Context context, int minWidth, int minHeight,
- int width, int height,
- int availableWidth, int availableHeight) {
- if (mDynamicGrid == null) {
- mDynamicGrid = new DynamicGrid(context,
+ @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
+ DeviceProfile initDynamicGrid(Context context) {
+ mDynamicGrid = createDynamicGrid(context, mDynamicGrid);
+ mDynamicGrid.getDeviceProfile().addCallback(this);
+ return mDynamicGrid.getDeviceProfile();
+ }
+
+ @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
+ static DynamicGrid createDynamicGrid(Context context, DynamicGrid dynamicGrid) {
+ // Determine the dynamic grid properties
+ WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
+ Display display = wm.getDefaultDisplay();
+
+ Point realSize = new Point();
+ display.getRealSize(realSize);
+ DisplayMetrics dm = new DisplayMetrics();
+ display.getMetrics(dm);
+
+ if (dynamicGrid == null) {
+ Point smallestSize = new Point();
+ Point largestSize = new Point();
+ display.getCurrentSizeRange(smallestSize, largestSize);
+
+ dynamicGrid = new DynamicGrid(context,
context.getResources(),
- minWidth, minHeight, width, height,
- availableWidth, availableHeight);
- mDynamicGrid.getDeviceProfile().addCallback(this);
+ Math.min(smallestSize.x, smallestSize.y),
+ Math.min(largestSize.x, largestSize.y),
+ realSize.x, realSize.y,
+ dm.widthPixels, dm.heightPixels);
}
// Update the icon size
- DeviceProfile grid = mDynamicGrid.getDeviceProfile();
- grid.updateFromConfiguration(context, context.getResources(), width, height,
- availableWidth, availableHeight);
- return grid;
+ DeviceProfile grid = dynamicGrid.getDeviceProfile();
+ grid.updateFromConfiguration(context, context.getResources(),
+ realSize.x, realSize.y,
+ dm.widthPixels, dm.heightPixels);
+ return dynamicGrid;
}
+
public DynamicGrid getDynamicGrid() {
return mDynamicGrid;
}
@@ -250,7 +276,7 @@ public class LauncherAppState implements DeviceProfile.DeviceProfileCallbacks {
public static boolean isDisableAllApps() {
// Returns false on non-dogfood builds.
return getInstance().mBuildInfo.isDogfoodBuild() &&
- Launcher.isPropertyEnabled(Launcher.DISABLE_ALL_APPS_PROPERTY);
+ Utilities.isPropertyEnabled(Launcher.DISABLE_ALL_APPS_PROPERTY);
}
public static boolean isDogfoodBuild() {
diff --git a/src/com/android/launcher3/LauncherBackupAgentHelper.java b/src/com/android/launcher3/LauncherBackupAgentHelper.java
index c20c6939d..3868a57f1 100644
--- a/src/com/android/launcher3/LauncherBackupAgentHelper.java
+++ b/src/com/android/launcher3/LauncherBackupAgentHelper.java
@@ -22,7 +22,6 @@ import android.app.backup.BackupManager;
import android.content.Context;
import android.database.Cursor;
import android.os.ParcelFileDescriptor;
-import android.provider.Settings;
import android.util.Log;
import java.io.IOException;
@@ -30,13 +29,14 @@ import java.io.IOException;
public class LauncherBackupAgentHelper extends BackupAgentHelper {
private static final String TAG = "LauncherBackupAgentHelper";
+
+ private static final String LAUNCHER_DATA_PREFIX = "L";
+
static final boolean VERBOSE = true;
static final boolean DEBUG = false;
private static BackupManager sBackupManager;
- protected static final String SETTING_RESTORE_ENABLED = "launcher_restore_enabled";
-
/**
* Notify the backup manager that out database is dirty.
*
@@ -51,42 +51,46 @@ public class LauncherBackupAgentHelper extends BackupAgentHelper {
sBackupManager.dataChanged();
}
- @Override
- public void onDestroy() {
- // There is only one process accessing this preference file, but the restore
- // modifies the file outside the normal codepaths, so it looks like another
- // process. This forces a reload of the file, in case this process persists.
- String spKey = LauncherAppState.getSharedPreferencesKey();
- getSharedPreferences(spKey, Context.MODE_MULTI_PROCESS);
- super.onDestroy();
- }
+ private LauncherBackupHelper mHelper;
@Override
public void onCreate() {
- boolean restoreEnabled = 0 != Settings.Secure.getInt(
- getContentResolver(), SETTING_RESTORE_ENABLED, 1);
- if (VERBOSE) Log.v(TAG, "restore is " + (restoreEnabled ? "enabled" : "disabled"));
-
- addHelper(LauncherBackupHelper.LAUNCHER_PREFS_PREFIX,
- new LauncherPreferencesBackupHelper(this,
- LauncherAppState.getSharedPreferencesKey(),
- restoreEnabled));
- addHelper(LauncherBackupHelper.LAUNCHER_PREFIX,
- new LauncherBackupHelper(this, restoreEnabled));
+ super.onCreate();
+ mHelper = new LauncherBackupHelper(this);
+ addHelper(LAUNCHER_DATA_PREFIX, mHelper);
}
@Override
public void onRestore(BackupDataInput data, int appVersionCode, ParcelFileDescriptor newState)
throws IOException {
- super.onRestore(data, appVersionCode, newState);
+ if (!Utilities.isLmpOrAbove()) {
+ // No restore for old devices.
+ Log.i(TAG, "You shall not pass!!!");
+ Log.d(TAG, "Restore is only supported on devices running Lollipop and above.");
+ return;
+ }
- // If no favorite was migrated, clear the data and start fresh.
- final Cursor c = getContentResolver().query(
- LauncherSettings.Favorites.CONTENT_URI_NO_NOTIFICATION, null, null, null, null);
- boolean hasData = c.moveToNext();
- c.close();
+ // Clear dB before restore
+ LauncherAppState.getLauncherProvider().createEmptyDB();
+
+ boolean hasData;
+ try {
+ super.onRestore(data, appVersionCode, newState);
+ // If no favorite was migrated, clear the data and start fresh.
+ final Cursor c = getContentResolver().query(
+ LauncherSettings.Favorites.CONTENT_URI_NO_NOTIFICATION, null, null, null, null);
+ hasData = c.moveToNext();
+ c.close();
+ } catch (Exception e) {
+ // If the restore fails, we should do a fresh start.
+ Log.e(TAG, "Restore failed", e);
+ hasData = false;
+ }
- if (!hasData) {
+ if (hasData && mHelper.restoreSuccessful) {
+ LauncherAppState.getLauncherProvider().clearFlagEmptyDbCreated();
+ LauncherClings.synchonouslyMarkFirstRunClingDismissed(this);
+ } else {
if (VERBOSE) Log.v(TAG, "Nothing was restored, clearing DB");
LauncherAppState.getLauncherProvider().createEmptyDB();
}
diff --git a/src/com/android/launcher3/LauncherBackupHelper.java b/src/com/android/launcher3/LauncherBackupHelper.java
index 201f3e9bb..437434748 100644
--- a/src/com/android/launcher3/LauncherBackupHelper.java
+++ b/src/com/android/launcher3/LauncherBackupHelper.java
@@ -15,22 +15,6 @@
*/
package com.android.launcher3;
-import com.google.protobuf.nano.InvalidProtocolBufferNanoException;
-import com.google.protobuf.nano.MessageNano;
-
-import com.android.launcher3.LauncherSettings.Favorites;
-import com.android.launcher3.LauncherSettings.WorkspaceScreens;
-import com.android.launcher3.backup.BackupProtos;
-import com.android.launcher3.backup.BackupProtos.CheckedMessage;
-import com.android.launcher3.backup.BackupProtos.Favorite;
-import com.android.launcher3.backup.BackupProtos.Journal;
-import com.android.launcher3.backup.BackupProtos.Key;
-import com.android.launcher3.backup.BackupProtos.Resource;
-import com.android.launcher3.backup.BackupProtos.Screen;
-import com.android.launcher3.backup.BackupProtos.Widget;
-import com.android.launcher3.compat.UserManagerCompat;
-import com.android.launcher3.compat.UserHandleCompat;
-
import android.app.backup.BackupDataInputStream;
import android.app.backup.BackupDataOutput;
import android.app.backup.BackupHelper;
@@ -42,6 +26,7 @@ import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.PackageManager.NameNotFoundException;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
@@ -51,6 +36,22 @@ import android.text.TextUtils;
import android.util.Base64;
import android.util.Log;
+import com.android.launcher3.LauncherSettings.Favorites;
+import com.android.launcher3.LauncherSettings.WorkspaceScreens;
+import com.android.launcher3.backup.BackupProtos;
+import com.android.launcher3.backup.BackupProtos.CheckedMessage;
+import com.android.launcher3.backup.BackupProtos.DeviceProfieData;
+import com.android.launcher3.backup.BackupProtos.Favorite;
+import com.android.launcher3.backup.BackupProtos.Journal;
+import com.android.launcher3.backup.BackupProtos.Key;
+import com.android.launcher3.backup.BackupProtos.Resource;
+import com.android.launcher3.backup.BackupProtos.Screen;
+import com.android.launcher3.backup.BackupProtos.Widget;
+import com.android.launcher3.compat.UserHandleCompat;
+import com.android.launcher3.compat.UserManagerCompat;
+import com.google.protobuf.nano.InvalidProtocolBufferNanoException;
+import com.google.protobuf.nano.MessageNano;
+
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
@@ -60,57 +61,53 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
-import java.util.Set;
import java.util.zip.CRC32;
/**
* Persist the launcher home state across calamities.
*/
public class LauncherBackupHelper implements BackupHelper {
-
private static final String TAG = "LauncherBackupHelper";
private static final boolean VERBOSE = LauncherBackupAgentHelper.VERBOSE;
private static final boolean DEBUG = LauncherBackupAgentHelper.DEBUG;
- private static final boolean DEBUG_PAYLOAD = false;
+ private static final int BACKUP_VERSION = 2;
private static final int MAX_JOURNAL_SIZE = 1000000;
+ // Journal key is such that it is always smaller than any dynamically generated
+ // key (any Base64 encoded string).
+ private static final String JOURNAL_KEY = "#";
+
/** icons are large, dribble them out */
private static final int MAX_ICONS_PER_PASS = 10;
/** widgets contain previews, which are very large, dribble them out */
private static final int MAX_WIDGETS_PER_PASS = 5;
- public static final int IMAGE_COMPRESSION_QUALITY = 75;
-
- public static final String LAUNCHER_PREFIX = "L";
-
- public static final String LAUNCHER_PREFS_PREFIX = "LP";
+ private static final int IMAGE_COMPRESSION_QUALITY = 75;
private static final Bitmap.CompressFormat IMAGE_FORMAT =
android.graphics.Bitmap.CompressFormat.PNG;
- private static BackupManager sBackupManager;
-
private static final String[] FAVORITE_PROJECTION = {
- Favorites._ID, // 0
- Favorites.MODIFIED, // 1
- Favorites.INTENT, // 2
- Favorites.APPWIDGET_PROVIDER, // 3
- Favorites.APPWIDGET_ID, // 4
- Favorites.CELLX, // 5
- Favorites.CELLY, // 6
- Favorites.CONTAINER, // 7
- Favorites.ICON, // 8
- Favorites.ICON_PACKAGE, // 9
- Favorites.ICON_RESOURCE, // 10
- Favorites.ICON_TYPE, // 11
- Favorites.ITEM_TYPE, // 12
- Favorites.SCREEN, // 13
- Favorites.SPANX, // 14
- Favorites.SPANY, // 15
- Favorites.TITLE, // 16
- Favorites.PROFILE_ID, // 17
+ Favorites._ID, // 0
+ Favorites.MODIFIED, // 1
+ Favorites.INTENT, // 2
+ Favorites.APPWIDGET_PROVIDER, // 3
+ Favorites.APPWIDGET_ID, // 4
+ Favorites.CELLX, // 5
+ Favorites.CELLY, // 6
+ Favorites.CONTAINER, // 7
+ Favorites.ICON, // 8
+ Favorites.ICON_PACKAGE, // 9
+ Favorites.ICON_RESOURCE, // 10
+ Favorites.ICON_TYPE, // 11
+ Favorites.ITEM_TYPE, // 12
+ Favorites.SCREEN, // 13
+ Favorites.SPANX, // 14
+ Favorites.SPANY, // 15
+ Favorites.TITLE, // 16
+ Favorites.PROFILE_ID, // 17
};
private static final int ID_INDEX = 0;
@@ -130,37 +127,50 @@ public class LauncherBackupHelper implements BackupHelper {
private static final int SPANX_INDEX = 14;
private static final int SPANY_INDEX = 15;
private static final int TITLE_INDEX = 16;
- private static final int PROFILE_ID_INDEX = 17;
private static final String[] SCREEN_PROJECTION = {
- WorkspaceScreens._ID, // 0
- WorkspaceScreens.MODIFIED, // 1
- WorkspaceScreens.SCREEN_RANK // 2
+ WorkspaceScreens._ID, // 0
+ WorkspaceScreens.MODIFIED, // 1
+ WorkspaceScreens.SCREEN_RANK // 2
};
private static final int SCREEN_RANK_INDEX = 2;
- private static IconCache mIconCache;
-
private final Context mContext;
+ private final HashSet<String> mExistingKeys;
+ private final ArrayList<Key> mKeys;
- private final boolean mRestoreEnabled;
-
+ private IconCache mIconCache;
+ private BackupManager mBackupManager;
private HashMap<ComponentName, AppWidgetProviderInfo> mWidgetMap;
+ private byte[] mBuffer = new byte[512];
+ private long mLastBackupRestoreTime;
- private final ArrayList<Key> mKeys;
+ private DeviceProfieData mCurrentProfile;
+ boolean restoreSuccessful;
- public LauncherBackupHelper(Context context, boolean restoreEnabled) {
+ public LauncherBackupHelper(Context context) {
mContext = context;
- mRestoreEnabled = restoreEnabled;
+ mExistingKeys = new HashSet<String>();
mKeys = new ArrayList<Key>();
+ restoreSuccessful = true;
}
private void dataChanged() {
- if (sBackupManager == null) {
- sBackupManager = new BackupManager(mContext);
+ if (mBackupManager == null) {
+ mBackupManager = new BackupManager(mContext);
+ }
+ mBackupManager.dataChanged();
+ }
+
+ private void applyJournal(Journal journal) {
+ mLastBackupRestoreTime = journal.t;
+ mExistingKeys.clear();
+ if (journal.key != null) {
+ for (Key key : journal.key) {
+ mExistingKeys.add(keyToBackupKey(key));
+ }
}
- sBackupManager.dataChanged();
}
/**
@@ -173,7 +183,6 @@ public class LauncherBackupHelper implements BackupHelper {
* @param oldState notes from the last backup
* @param data incremental key/value pairs to persist off-device
* @param newState notes for the next backup
- * @throws IOException
*/
@Override
public void performBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
@@ -181,86 +190,149 @@ public class LauncherBackupHelper implements BackupHelper {
if (VERBOSE) Log.v(TAG, "onBackup");
Journal in = readJournal(oldState);
- Journal out = new Journal();
+ if (!launcherIsReady()) {
+ // Perform backup later.
+ writeJournal(newState, in);
+ return;
+ }
+ Log.v(TAG, "lastBackupTime = " + in.t);
+ mKeys.clear();
+ applyJournal(in);
- long lastBackupTime = in.t;
- out.t = System.currentTimeMillis();
- out.rows = 0;
- out.bytes = 0;
+ // Record the time before performing backup so that entries edited while the backup
+ // was going on, do not get missed in next backup.
+ long newBackupTime = System.currentTimeMillis();
- Log.v(TAG, "lastBackupTime = " + lastBackupTime);
+ try {
+ backupFavorites(data);
+ backupScreens(data);
+ backupIcons(data);
+ backupWidgets(data);
+
+ // Delete any key which still exist in the old backup, but is not valid anymore.
+ HashSet<String> validKeys = new HashSet<String>();
+ for (Key key : mKeys) {
+ validKeys.add(keyToBackupKey(key));
+ }
+ mExistingKeys.removeAll(validKeys);
- ArrayList<Key> keys = new ArrayList<Key>();
- if (launcherIsReady()) {
- try {
- backupFavorites(in, data, out, keys);
- backupScreens(in, data, out, keys);
- backupIcons(in, data, out, keys);
- backupWidgets(in, data, out, keys);
- } catch (IOException e) {
- Log.e(TAG, "launcher backup has failed", e);
+ // Delete anything left in the existing keys.
+ for (String deleted: mExistingKeys) {
+ if (VERBOSE) Log.v(TAG, "dropping deleted item " + deleted);
+ data.writeEntityHeader(deleted, -1);
}
- out.key = keys.toArray(new BackupProtos.Key[keys.size()]);
- } else {
- out = in;
+
+ mExistingKeys.clear();
+ mLastBackupRestoreTime = newBackupTime;
+
+ // We store the journal at two places.
+ // 1) Storing it in newState allows us to do partial backups by comparing old state
+ // 2) Storing it in backup data allows us to validate keys during restore
+ Journal state = getCurrentStateJournal();
+ writeRowToBackup(JOURNAL_KEY, state, data);
+ } catch (IOException e) {
+ Log.e(TAG, "launcher backup has failed", e);
}
- writeJournal(newState, out);
- Log.v(TAG, "onBackup: wrote " + out.bytes + "b in " + out.rows + " rows.");
+ writeNewStateDescription(newState);
+ }
+
+ /**
+ * @return true if the backup corresponding to oldstate can be successfully applied
+ * to this device.
+ */
+ private boolean isBackupCompatible(Journal oldState) {
+ DeviceProfieData currentProfile = getDeviceProfieData();
+
+ DeviceProfieData oldProfile = oldState.profile;
+
+ if (oldProfile == null || oldProfile.desktopCols == 0) {
+ // Profile info is not valid, ignore the check.
+ return true;
+ }
+
+ boolean isHotsetCompatible = false;
+ if (currentProfile.allappsRank >= oldProfile.hotseatCount) {
+ isHotsetCompatible = true;
+ }
+ if ((currentProfile.hotseatCount >= oldProfile.hotseatCount) &&
+ (currentProfile.allappsRank == oldProfile.allappsRank)) {
+ isHotsetCompatible = true;
+ }
+
+ return isHotsetCompatible && (currentProfile.desktopCols >= oldProfile.desktopCols)
+ && (currentProfile.desktopRows >= oldProfile.desktopRows);
}
/**
* Restore launcher configuration from the restored data stream.
- *
- * <P>Keys may arrive in any order.
+ * It assumes that the keys will arrive in lexical order. So if the journal was present in the
+ * backup, it should arrive first.
*
* @param data the key/value pair from the server
*/
@Override
public void restoreEntity(BackupDataInputStream data) {
- if (VERBOSE) Log.v(TAG, "restoreEntity");
- byte[] buffer = new byte[512];
- String backupKey = data.getKey();
- int dataSize = data.size();
- if (buffer.length < dataSize) {
- buffer = new byte[dataSize];
- }
- Key key = null;
- int bytesRead = 0;
- try {
- bytesRead = data.read(buffer, 0, dataSize);
- if (DEBUG) Log.d(TAG, "read " + bytesRead + " of " + dataSize + " available");
- } catch (IOException e) {
- Log.e(TAG, "failed to read entity from restore data", e);
+ if (!restoreSuccessful) {
+ return;
+ }
+
+ int dataSize = data.size();
+ if (mBuffer.length < dataSize) {
+ mBuffer = new byte[dataSize];
}
try {
- key = backupKeyToKey(backupKey);
+ int bytesRead = data.read(mBuffer, 0, dataSize);
+ if (DEBUG) Log.d(TAG, "read " + bytesRead + " of " + dataSize + " available");
+ String backupKey = data.getKey();
+
+ if (JOURNAL_KEY.equals(backupKey)) {
+ if (VERBOSE) Log.v(TAG, "Journal entry restored");
+ if (!mKeys.isEmpty()) {
+ // We received the journal key after a restore key.
+ Log.wtf(TAG, keyToBackupKey(mKeys.get(0)) + " received after " + JOURNAL_KEY);
+ restoreSuccessful = false;
+ return;
+ }
+
+ Journal journal = new Journal();
+ MessageNano.mergeFrom(journal, readCheckedBytes(mBuffer, dataSize));
+ applyJournal(journal);
+ restoreSuccessful = isBackupCompatible(journal);
+ return;
+ }
+
+ if (!mExistingKeys.isEmpty() && !mExistingKeys.contains(backupKey)) {
+ if (DEBUG) Log.e(TAG, "Ignoring key not present in the backup state " + backupKey);
+ return;
+ }
+ Key key = backupKeyToKey(backupKey);
mKeys.add(key);
switch (key.type) {
case Key.FAVORITE:
- restoreFavorite(key, buffer, dataSize, mKeys);
+ restoreFavorite(key, mBuffer, dataSize);
break;
case Key.SCREEN:
- restoreScreen(key, buffer, dataSize, mKeys);
+ restoreScreen(key, mBuffer, dataSize);
break;
case Key.ICON:
- restoreIcon(key, buffer, dataSize, mKeys);
+ restoreIcon(key, mBuffer, dataSize);
break;
case Key.WIDGET:
- restoreWidget(key, buffer, dataSize, mKeys);
+ restoreWidget(key, mBuffer, dataSize);
break;
default:
Log.w(TAG, "unknown restore entity type: " + key.type);
+ mKeys.remove(key);
break;
}
- } catch (KeyParsingException e) {
- Log.w(TAG, "ignoring unparsable backup key: " + backupKey);
+ } catch (IOException e) {
+ Log.w(TAG, "ignoring unparsable backup entry", e);
}
-
}
/**
@@ -270,63 +342,76 @@ public class LauncherBackupHelper implements BackupHelper {
*/
@Override
public void writeNewStateDescription(ParcelFileDescriptor newState) {
- // clear the output journal time, to force a full backup to
- // will catch any changes the restore process might have made
- Journal out = new Journal();
- out.t = 0;
- out.key = mKeys.toArray(new BackupProtos.Key[mKeys.size()]);
- writeJournal(newState, out);
- Log.v(TAG, "onRestore: read " + mKeys.size() + " rows");
- mKeys.clear();
+ writeJournal(newState, getCurrentStateJournal());
+ }
+
+ private Journal getCurrentStateJournal() {
+ Journal journal = new Journal();
+ journal.t = mLastBackupRestoreTime;
+ journal.key = mKeys.toArray(new BackupProtos.Key[mKeys.size()]);
+ journal.appVersion = getAppVersion();
+ journal.backupVersion = BACKUP_VERSION;
+ journal.profile = getDeviceProfieData();
+ return journal;
+ }
+
+ private int getAppVersion() {
+ try {
+ return mContext.getPackageManager()
+ .getPackageInfo(mContext.getPackageName(), 0).versionCode;
+ } catch (NameNotFoundException e) {
+ return 0;
+ }
+ }
+
+ /**
+ * @return the current device profile information.
+ */
+ private DeviceProfieData getDeviceProfieData() {
+ if (mCurrentProfile != null) {
+ return mCurrentProfile;
+ }
+ final Context applicationContext = mContext.getApplicationContext();
+ DeviceProfile profile = LauncherAppState.createDynamicGrid(applicationContext, null)
+ .getDeviceProfile();
+
+ mCurrentProfile = new DeviceProfieData();
+ mCurrentProfile.desktopRows = profile.numRows;
+ mCurrentProfile.desktopCols = profile.numColumns;
+ mCurrentProfile.hotseatCount = profile.numHotseatIcons;
+ mCurrentProfile.allappsRank = profile.hotseatAllAppsRank;
+ return mCurrentProfile;
}
/**
* Write all modified favorites to the data stream.
*
- *
- * @param in notes from last backup
* @param data output stream for key/value pairs
- * @param out notes about this backup
- * @param keys keys to mark as clean in the notes for next backup
* @throws IOException
*/
- private void backupFavorites(Journal in, BackupDataOutput data, Journal out,
- ArrayList<Key> keys)
- throws IOException {
- // read the old ID set
- Set<String> savedIds = getSavedIdsByType(Key.FAVORITE, in);
- if (DEBUG) Log.d(TAG, "favorite savedIds.size()=" + savedIds.size());
-
+ private void backupFavorites(BackupDataOutput data) throws IOException {
// persist things that have changed since the last backup
ContentResolver cr = mContext.getContentResolver();
// Don't backup apps in other profiles for now.
Cursor cursor = cr.query(Favorites.CONTENT_URI, FAVORITE_PROJECTION,
getUserSelectionArg(), null, null);
- Set<String> currentIds = new HashSet<String>(cursor.getCount());
try {
cursor.moveToPosition(-1);
while(cursor.moveToNext()) {
final long id = cursor.getLong(ID_INDEX);
final long updateTime = cursor.getLong(ID_MODIFIED);
Key key = getKey(Key.FAVORITE, id);
- keys.add(key);
+ mKeys.add(key);
final String backupKey = keyToBackupKey(key);
- currentIds.add(backupKey);
- if (!savedIds.contains(backupKey) || updateTime >= in.t) {
- byte[] blob = packFavorite(cursor);
- writeRowToBackup(key, blob, out, data);
+ if (!mExistingKeys.contains(backupKey) || updateTime >= mLastBackupRestoreTime) {
+ writeRowToBackup(key, packFavorite(cursor), data);
} else {
- if (VERBOSE) Log.v(TAG, "favorite " + id + " was too old: " + updateTime);
+ if (DEBUG) Log.d(TAG, "favorite already backup up: " + id);
}
}
} finally {
cursor.close();
}
- if (DEBUG) Log.d(TAG, "favorite currentIds.size()=" + currentIds.size());
-
- // these IDs must have been deleted
- savedIds.removeAll(currentIds);
- out.rows += removeDeletedKeysFromBackup(savedIds, data);
}
/**
@@ -337,74 +422,46 @@ public class LauncherBackupHelper implements BackupHelper {
* @param key identifier for the row
* @param buffer the serialized proto from the stream, may be larger than dataSize
* @param dataSize the size of the proto from the stream
- * @param keys keys to mark as clean in the notes for next backup
*/
- private void restoreFavorite(Key key, byte[] buffer, int dataSize, ArrayList<Key> keys) {
+ private void restoreFavorite(Key key, byte[] buffer, int dataSize) throws IOException {
if (VERBOSE) Log.v(TAG, "unpacking favorite " + key.id);
if (DEBUG) Log.d(TAG, "read (" + buffer.length + "): " +
Base64.encodeToString(buffer, 0, dataSize, Base64.NO_WRAP));
- if (!mRestoreEnabled) {
- if (VERBOSE) Log.v(TAG, "restore not enabled: skipping database mutation");
- return;
- }
-
- try {
- ContentResolver cr = mContext.getContentResolver();
- ContentValues values = unpackFavorite(buffer, 0, dataSize);
- cr.insert(Favorites.CONTENT_URI_NO_NOTIFICATION, values);
- } catch (InvalidProtocolBufferNanoException e) {
- Log.e(TAG, "failed to decode favorite", e);
- }
+ ContentResolver cr = mContext.getContentResolver();
+ ContentValues values = unpackFavorite(buffer, dataSize);
+ cr.insert(Favorites.CONTENT_URI_NO_NOTIFICATION, values);
}
/**
* Write all modified screens to the data stream.
*
- *
- * @param in notes from last backup
* @param data output stream for key/value pairs
- * @param out notes about this backup
- * @param keys keys to mark as clean in the notes for next backup
* @throws IOException
*/
- private void backupScreens(Journal in, BackupDataOutput data, Journal out,
- ArrayList<Key> keys)
- throws IOException {
- // read the old ID set
- Set<String> savedIds = getSavedIdsByType(Key.SCREEN, in);
- if (DEBUG) Log.d(TAG, "screen savedIds.size()=" + savedIds.size());
-
+ private void backupScreens(BackupDataOutput data) throws IOException {
// persist things that have changed since the last backup
ContentResolver cr = mContext.getContentResolver();
Cursor cursor = cr.query(WorkspaceScreens.CONTENT_URI, SCREEN_PROJECTION,
null, null, null);
- Set<String> currentIds = new HashSet<String>(cursor.getCount());
try {
cursor.moveToPosition(-1);
- if (DEBUG) Log.d(TAG, "dumping screens after: " + in.t);
+ if (DEBUG) Log.d(TAG, "dumping screens after: " + mLastBackupRestoreTime);
while(cursor.moveToNext()) {
final long id = cursor.getLong(ID_INDEX);
final long updateTime = cursor.getLong(ID_MODIFIED);
Key key = getKey(Key.SCREEN, id);
- keys.add(key);
+ mKeys.add(key);
final String backupKey = keyToBackupKey(key);
- currentIds.add(backupKey);
- if (!savedIds.contains(backupKey) || updateTime >= in.t) {
- byte[] blob = packScreen(cursor);
- writeRowToBackup(key, blob, out, data);
+ if (!mExistingKeys.contains(backupKey) || updateTime >= mLastBackupRestoreTime) {
+ writeRowToBackup(key, packScreen(cursor), data);
} else {
- if (VERBOSE) Log.v(TAG, "screen " + id + " was too old: " + updateTime);
+ if (VERBOSE) Log.v(TAG, "screen already backup up " + id);
}
}
} finally {
cursor.close();
}
- if (DEBUG) Log.d(TAG, "screen currentIds.size()=" + currentIds.size());
-
- // these IDs must have been deleted
- savedIds.removeAll(currentIds);
- out.rows += removeDeletedKeysFromBackup(savedIds, data);
}
/**
@@ -415,40 +472,24 @@ public class LauncherBackupHelper implements BackupHelper {
* @param key identifier for the row
* @param buffer the serialized proto from the stream, may be larger than dataSize
* @param dataSize the size of the proto from the stream
- * @param keys keys to mark as clean in the notes for next backup
*/
- private void restoreScreen(Key key, byte[] buffer, int dataSize, ArrayList<Key> keys) {
+ private void restoreScreen(Key key, byte[] buffer, int dataSize) throws IOException {
if (VERBOSE) Log.v(TAG, "unpacking screen " + key.id);
if (DEBUG) Log.d(TAG, "read (" + buffer.length + "): " +
Base64.encodeToString(buffer, 0, dataSize, Base64.NO_WRAP));
- if (!mRestoreEnabled) {
- if (VERBOSE) Log.v(TAG, "restore not enabled: skipping database mutation");
- return;
- }
-
- try {
- ContentResolver cr = mContext.getContentResolver();
- ContentValues values = unpackScreen(buffer, 0, dataSize);
- cr.insert(WorkspaceScreens.CONTENT_URI, values);
-
- } catch (InvalidProtocolBufferNanoException e) {
- Log.e(TAG, "failed to decode screen", e);
- }
+ ContentResolver cr = mContext.getContentResolver();
+ ContentValues values = unpackScreen(buffer, dataSize);
+ cr.insert(WorkspaceScreens.CONTENT_URI, values);
}
/**
* Write all the static icon resources we need to render placeholders
* for a package that is not installed.
*
- * @param in notes from last backup
* @param data output stream for key/value pairs
- * @param out notes about this backup
- * @param keys keys to mark as clean in the notes for next backup
- * @throws IOException
*/
- private void backupIcons(Journal in, BackupDataOutput data, Journal out,
- ArrayList<Key> keys) throws IOException {
+ private void backupIcons(BackupDataOutput data) throws IOException {
// persist icons that haven't been persisted yet
if (!initializeIconCache()) {
dataChanged(); // try again later
@@ -458,21 +499,14 @@ public class LauncherBackupHelper implements BackupHelper {
final ContentResolver cr = mContext.getContentResolver();
final int dpi = mContext.getResources().getDisplayMetrics().densityDpi;
final UserHandleCompat myUserHandle = UserHandleCompat.myUserHandle();
-
- // read the old ID set
- Set<String> savedIds = getSavedIdsByType(Key.ICON, in);
- if (DEBUG) Log.d(TAG, "icon savedIds.size()=" + savedIds.size());
+ int backupUpIconCount = 0;
// Don't backup apps in other profiles for now.
- int startRows = out.rows;
- if (DEBUG) Log.d(TAG, "starting here: " + startRows);
-
String where = "(" + Favorites.ITEM_TYPE + "=" + Favorites.ITEM_TYPE_APPLICATION + " OR " +
Favorites.ITEM_TYPE + "=" + Favorites.ITEM_TYPE_SHORTCUT + ") AND " +
getUserSelectionArg();
Cursor cursor = cr.query(Favorites.CONTENT_URI, FAVORITE_PROJECTION,
where, null, null);
- Set<String> currentIds = new HashSet<String>(cursor.getCount());
try {
cursor.moveToPosition(-1);
while(cursor.moveToNext()) {
@@ -486,27 +520,26 @@ public class LauncherBackupHelper implements BackupHelper {
if (cn != null) {
key = getKey(Key.ICON, cn.flattenToShortString());
backupKey = keyToBackupKey(key);
- currentIds.add(backupKey);
} else {
Log.w(TAG, "empty intent on application favorite: " + id);
}
- if (savedIds.contains(backupKey)) {
- if (VERBOSE) Log.v(TAG, "already saved icon " + backupKey);
+ if (mExistingKeys.contains(backupKey)) {
+ if (DEBUG) Log.d(TAG, "already saved icon " + backupKey);
// remember that we already backed this up previously
- keys.add(key);
+ mKeys.add(key);
} else if (backupKey != null) {
- if (DEBUG) Log.d(TAG, "I can count this high: " + out.rows);
- if ((out.rows - startRows) < MAX_ICONS_PER_PASS) {
- if (VERBOSE) Log.v(TAG, "saving icon " + backupKey);
+ if (DEBUG) Log.d(TAG, "I can count this high: " + backupUpIconCount);
+ if (backupUpIconCount < MAX_ICONS_PER_PASS) {
+ if (DEBUG) Log.d(TAG, "saving icon " + backupKey);
Bitmap icon = mIconCache.getIcon(intent, myUserHandle);
- keys.add(key);
if (icon != null && !mIconCache.isDefaultIcon(icon, myUserHandle)) {
- byte[] blob = packIcon(dpi, icon);
- writeRowToBackup(key, blob, out, data);
+ writeRowToBackup(key, packIcon(dpi, icon), data);
+ mKeys.add(key);
+ backupUpIconCount ++;
}
} else {
- if (VERBOSE) Log.d(TAG, "deferring icon backup " + backupKey);
+ if (VERBOSE) Log.v(TAG, "deferring icon backup " + backupKey);
// too many icons for this pass, request another.
dataChanged();
}
@@ -521,11 +554,6 @@ public class LauncherBackupHelper implements BackupHelper {
} finally {
cursor.close();
}
- if (DEBUG) Log.d(TAG, "icon currentIds.size()=" + currentIds.size());
-
- // these IDs must have been deleted
- savedIds.removeAll(currentIds);
- out.rows += removeDeletedKeysFromBackup(savedIds, data);
}
/**
@@ -536,55 +564,32 @@ public class LauncherBackupHelper implements BackupHelper {
* @param key identifier for the row
* @param buffer the serialized proto from the stream, may be larger than dataSize
* @param dataSize the size of the proto from the stream
- * @param keys keys to mark as clean in the notes for next backup
*/
- private void restoreIcon(Key key, byte[] buffer, int dataSize, ArrayList<Key> keys) {
+ private void restoreIcon(Key key, byte[] buffer, int dataSize) throws IOException {
if (VERBOSE) Log.v(TAG, "unpacking icon " + key.id);
if (DEBUG) Log.d(TAG, "read (" + buffer.length + "): " +
Base64.encodeToString(buffer, 0, dataSize, Base64.NO_WRAP));
- try {
- Resource res = unpackIcon(buffer, 0, dataSize);
- if (DEBUG) {
- Log.d(TAG, "unpacked " + res.dpi + " dpi icon");
- }
- if (DEBUG_PAYLOAD) {
- Log.d(TAG, "read " +
- Base64.encodeToString(res.data, 0, res.data.length,
- Base64.NO_WRAP));
- }
- Bitmap icon = BitmapFactory.decodeByteArray(res.data, 0, res.data.length);
- if (icon == null) {
- Log.w(TAG, "failed to unpack icon for " + key.name);
- }
-
- if (!mRestoreEnabled) {
- if (VERBOSE) {
- Log.v(TAG, "restore not enabled: skipping database mutation");
- }
- return;
- } else {
- if (VERBOSE) Log.v(TAG, "saving restored icon as: " + key.name);
- IconCache.preloadIcon(mContext, ComponentName.unflattenFromString(key.name),
- icon, res.dpi);
- }
- } catch (IOException e) {
- Log.d(TAG, "failed to save restored icon for: " + key.name, e);
+ Resource res = unpackProto(new Resource(), buffer, dataSize);
+ if (DEBUG) {
+ Log.d(TAG, "unpacked " + res.dpi + " dpi icon");
+ }
+ Bitmap icon = BitmapFactory.decodeByteArray(res.data, 0, res.data.length);
+ if (icon == null) {
+ Log.w(TAG, "failed to unpack icon for " + key.name);
}
+ if (VERBOSE) Log.v(TAG, "saving restored icon as: " + key.name);
+ IconCache.preloadIcon(mContext, ComponentName.unflattenFromString(key.name), icon, res.dpi);
}
/**
* Write all the static widget resources we need to render placeholders
* for a package that is not installed.
*
- * @param in notes from last backup
* @param data output stream for key/value pairs
- * @param out notes about this backup
- * @param keys keys to mark as clean in the notes for next backup
* @throws IOException
*/
- private void backupWidgets(Journal in, BackupDataOutput data, Journal out,
- ArrayList<Key> keys) throws IOException {
+ private void backupWidgets(BackupDataOutput data) throws IOException {
// persist static widget info that hasn't been persisted yet
final LauncherAppState appState = LauncherAppState.getInstanceNoCreate();
if (appState == null || !initializeIconCache()) {
@@ -597,18 +602,12 @@ public class LauncherBackupHelper implements BackupHelper {
final int dpi = mContext.getResources().getDisplayMetrics().densityDpi;
final DeviceProfile profile = appState.getDynamicGrid().getDeviceProfile();
if (DEBUG) Log.d(TAG, "cellWidthPx: " + profile.cellWidthPx);
+ int backupWidgetCount = 0;
- // read the old ID set
- Set<String> savedIds = getSavedIdsByType(Key.WIDGET, in);
- if (DEBUG) Log.d(TAG, "widgets savedIds.size()=" + savedIds.size());
-
- int startRows = out.rows;
- if (DEBUG) Log.d(TAG, "starting here: " + startRows);
String where = Favorites.ITEM_TYPE + "=" + Favorites.ITEM_TYPE_APPWIDGET + " AND "
+ getUserSelectionArg();
Cursor cursor = cr.query(Favorites.CONTENT_URI, FAVORITE_PROJECTION,
where, null, null);
- Set<String> currentIds = new HashSet<String>(cursor.getCount());
try {
cursor.moveToPosition(-1);
while(cursor.moveToNext()) {
@@ -622,27 +621,25 @@ public class LauncherBackupHelper implements BackupHelper {
if (provider != null) {
key = getKey(Key.WIDGET, providerName);
backupKey = keyToBackupKey(key);
- currentIds.add(backupKey);
} else {
Log.w(TAG, "empty intent on appwidget: " + id);
}
- if (savedIds.contains(backupKey)) {
- if (VERBOSE) Log.v(TAG, "already saved widget " + backupKey);
+ if (mExistingKeys.contains(backupKey)) {
+ if (DEBUG) Log.d(TAG, "already saved widget " + backupKey);
// remember that we already backed this up previously
- keys.add(key);
+ mKeys.add(key);
} else if (backupKey != null) {
- if (DEBUG) Log.d(TAG, "I can count this high: " + out.rows);
- if ((out.rows - startRows) < MAX_WIDGETS_PER_PASS) {
- if (VERBOSE) Log.v(TAG, "saving widget " + backupKey);
+ if (DEBUG) Log.d(TAG, "I can count this high: " + backupWidgetCount);
+ if (backupWidgetCount < MAX_WIDGETS_PER_PASS) {
+ if (DEBUG) Log.d(TAG, "saving widget " + backupKey);
previewLoader.setPreviewSize(spanX * profile.cellWidthPx,
spanY * profile.cellHeightPx, widgetSpacingLayout);
- byte[] blob = packWidget(dpi, previewLoader, mIconCache, provider);
- keys.add(key);
- writeRowToBackup(key, blob, out, data);
-
+ writeRowToBackup(key, packWidget(dpi, previewLoader, mIconCache, provider), data);
+ mKeys.add(key);
+ backupWidgetCount ++;
} else {
- if (VERBOSE) Log.d(TAG, "deferring widget backup " + backupKey);
+ if (VERBOSE) Log.v(TAG, "deferring widget backup " + backupKey);
// too many widgets for this pass, request another.
dataChanged();
}
@@ -651,11 +648,6 @@ public class LauncherBackupHelper implements BackupHelper {
} finally {
cursor.close();
}
- if (DEBUG) Log.d(TAG, "widget currentIds.size()=" + currentIds.size());
-
- // these IDs must have been deleted
- savedIds.removeAll(currentIds);
- out.rows += removeDeletedKeysFromBackup(savedIds, data);
}
/**
@@ -666,35 +658,25 @@ public class LauncherBackupHelper implements BackupHelper {
* @param key identifier for the row
* @param buffer the serialized proto from the stream, may be larger than dataSize
* @param dataSize the size of the proto from the stream
- * @param keys keys to mark as clean in the notes for next backup
*/
- private void restoreWidget(Key key, byte[] buffer, int dataSize, ArrayList<Key> keys) {
+ private void restoreWidget(Key key, byte[] buffer, int dataSize) throws IOException {
if (VERBOSE) Log.v(TAG, "unpacking widget " + key.id);
if (DEBUG) Log.d(TAG, "read (" + buffer.length + "): " +
Base64.encodeToString(buffer, 0, dataSize, Base64.NO_WRAP));
- try {
- Widget widget = unpackWidget(buffer, 0, dataSize);
- if (DEBUG) Log.d(TAG, "unpacked " + widget.provider);
- if (widget.icon.data != null) {
- Bitmap icon = BitmapFactory
- .decodeByteArray(widget.icon.data, 0, widget.icon.data.length);
- if (icon == null) {
- Log.w(TAG, "failed to unpack widget icon for " + key.name);
- } else {
- IconCache.preloadIcon(mContext, ComponentName.unflattenFromString(widget.provider),
- icon, widget.icon.dpi);
- }
- }
-
- if (!mRestoreEnabled) {
- if (VERBOSE) Log.v(TAG, "restore not enabled: skipping database mutation");
- return;
+ Widget widget = unpackProto(new Widget(), buffer, dataSize);
+ if (DEBUG) Log.d(TAG, "unpacked " + widget.provider);
+ if (widget.icon.data != null) {
+ Bitmap icon = BitmapFactory
+ .decodeByteArray(widget.icon.data, 0, widget.icon.data.length);
+ if (icon == null) {
+ Log.w(TAG, "failed to unpack widget icon for " + key.name);
} else {
- // future site of widget table mutation
+ IconCache.preloadIcon(mContext, ComponentName.unflattenFromString(widget.provider),
+ icon, widget.icon.dpi);
}
- } catch (InvalidProtocolBufferNanoException e) {
- Log.e(TAG, "failed to decode widget", e);
}
+
+ // future site of widget table mutation
}
/** create a new key, with an integer ID.
@@ -729,42 +711,18 @@ public class LauncherBackupHelper implements BackupHelper {
}
/** keys need to be strings, decode and parse. */
- private Key backupKeyToKey(String backupKey) throws KeyParsingException {
+ private Key backupKeyToKey(String backupKey) throws InvalidBackupException {
try {
Key key = Key.parseFrom(Base64.decode(backupKey, Base64.DEFAULT));
if (key.checksum != checkKey(key)) {
key = null;
- throw new KeyParsingException("invalid key read from stream" + backupKey);
+ throw new InvalidBackupException("invalid key read from stream" + backupKey);
}
return key;
} catch (InvalidProtocolBufferNanoException e) {
- throw new KeyParsingException(e);
+ throw new InvalidBackupException(e);
} catch (IllegalArgumentException e) {
- throw new KeyParsingException(e);
- }
- }
-
- private String getKeyName(Key key) {
- if (TextUtils.isEmpty(key.name)) {
- return Long.toString(key.id);
- } else {
- return key.name;
- }
-
- }
-
- private String geKeyType(Key key) {
- switch (key.type) {
- case Key.FAVORITE:
- return "favorite";
- case Key.SCREEN:
- return "screen";
- case Key.ICON:
- return "icon";
- case Key.WIDGET:
- return "widget";
- default:
- return "anonymous";
+ throw new InvalidBackupException(e);
}
}
@@ -781,7 +739,7 @@ public class LauncherBackupHelper implements BackupHelper {
}
/** Serialize a Favorite for persistence, including a checksum wrapper. */
- private byte[] packFavorite(Cursor c) {
+ private Favorite packFavorite(Cursor c) {
Favorite favorite = new Favorite();
favorite.id = c.getLong(ID_INDEX);
favorite.screen = c.getInt(SCREEN_INDEX);
@@ -819,7 +777,7 @@ public class LauncherBackupHelper implements BackupHelper {
favorite.intent = intent.toUri(0);
} catch (URISyntaxException e) {
Log.e(TAG, "Invalid intent", e);
- }
+ }
}
favorite.itemType = c.getInt(ITEM_TYPE_INDEX);
if (favorite.itemType == Favorites.ITEM_TYPE_APPWIDGET) {
@@ -830,16 +788,13 @@ public class LauncherBackupHelper implements BackupHelper {
}
}
- return writeCheckedBytes(favorite);
+ return favorite;
}
/** Deserialize a Favorite from persistence, after verifying checksum wrapper. */
- private ContentValues unpackFavorite(byte[] buffer, int offset, int dataSize)
- throws InvalidProtocolBufferNanoException {
- Favorite favorite = new Favorite();
- MessageNano.mergeFrom(favorite, readCheckedBytes(buffer, offset, dataSize));
- if (VERBOSE) Log.v(TAG, "unpacked favorite " + favorite.itemType + ", " +
- (TextUtils.isEmpty(favorite.title) ? favorite.id : favorite.title));
+ private ContentValues unpackFavorite(byte[] buffer, int dataSize)
+ throws IOException {
+ Favorite favorite = unpackProto(new Favorite(), buffer, dataSize);
ContentValues values = new ContentValues();
values.put(Favorites._ID, favorite.id);
values.put(Favorites.SCREEN, favorite.screen);
@@ -871,6 +826,8 @@ public class LauncherBackupHelper implements BackupHelper {
UserManagerCompat.getInstance(mContext).getSerialNumberForUser(myUserHandle);
values.put(LauncherSettings.Favorites.PROFILE_ID, userSerialNumber);
+ DeviceProfieData currentProfile = getDeviceProfieData();
+
if (favorite.itemType == Favorites.ITEM_TYPE_APPWIDGET) {
if (!TextUtils.isEmpty(favorite.appWidgetProvider)) {
values.put(Favorites.APPWIDGET_PROVIDER, favorite.appWidgetProvider);
@@ -880,29 +837,48 @@ public class LauncherBackupHelper implements BackupHelper {
LauncherAppWidgetInfo.FLAG_ID_NOT_VALID |
LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY |
LauncherAppWidgetInfo.FLAG_UI_NOT_READY);
+
+ // Verify placement
+ if (((favorite.cellX + favorite.spanX) > currentProfile.desktopCols)
+ || ((favorite.cellY + favorite.spanY) > currentProfile.desktopRows)) {
+ restoreSuccessful = false;
+ throw new InvalidBackupException("Widget not in screen bounds, aborting restore");
+ }
} else {
// Let LauncherModel know we've been here.
values.put(LauncherSettings.Favorites.RESTORED, 1);
+
+ // Verify placement
+ if (favorite.container == Favorites.CONTAINER_HOTSEAT) {
+ if ((favorite.screen >= currentProfile.hotseatCount)
+ || (favorite.screen == currentProfile.allappsRank)) {
+ restoreSuccessful = false;
+ throw new InvalidBackupException("Item not in hotseat bounds, aborting restore");
+ }
+ } else {
+ if ((favorite.cellX >= currentProfile.desktopCols)
+ || (favorite.cellY >= currentProfile.desktopRows)) {
+ restoreSuccessful = false;
+ throw new InvalidBackupException("Item not in desktop bounds, aborting restore");
+ }
+ }
}
return values;
}
/** Serialize a Screen for persistence, including a checksum wrapper. */
- private byte[] packScreen(Cursor c) {
+ private Screen packScreen(Cursor c) {
Screen screen = new Screen();
screen.id = c.getLong(ID_INDEX);
screen.rank = c.getInt(SCREEN_RANK_INDEX);
-
- return writeCheckedBytes(screen);
+ return screen;
}
/** Deserialize a Screen from persistence, after verifying checksum wrapper. */
- private ContentValues unpackScreen(byte[] buffer, int offset, int dataSize)
+ private ContentValues unpackScreen(byte[] buffer, int dataSize)
throws InvalidProtocolBufferNanoException {
- Screen screen = new Screen();
- MessageNano.mergeFrom(screen, readCheckedBytes(buffer, offset, dataSize));
- if (VERBOSE) Log.v(TAG, "unpacked screen " + screen.id + "/" + screen.rank);
+ Screen screen = unpackProto(new Screen(), buffer, dataSize);
ContentValues values = new ContentValues();
values.put(WorkspaceScreens._ID, screen.id);
values.put(WorkspaceScreens.SCREEN_RANK, screen.rank);
@@ -910,27 +886,18 @@ public class LauncherBackupHelper implements BackupHelper {
}
/** Serialize an icon Resource for persistence, including a checksum wrapper. */
- private byte[] packIcon(int dpi, Bitmap icon) {
+ private Resource packIcon(int dpi, Bitmap icon) {
Resource res = new Resource();
res.dpi = dpi;
ByteArrayOutputStream os = new ByteArrayOutputStream();
if (icon.compress(IMAGE_FORMAT, IMAGE_COMPRESSION_QUALITY, os)) {
res.data = os.toByteArray();
}
- return writeCheckedBytes(res);
- }
-
- /** Deserialize an icon resource from persistence, after verifying checksum wrapper. */
- private static Resource unpackIcon(byte[] buffer, int offset, int dataSize)
- throws InvalidProtocolBufferNanoException {
- Resource res = new Resource();
- MessageNano.mergeFrom(res, readCheckedBytes(buffer, offset, dataSize));
- if (VERBOSE) Log.v(TAG, "unpacked icon " + res.dpi + "/" + res.data.length);
return res;
}
/** Serialize a widget for persistence, including a checksum wrapper. */
- private byte[] packWidget(int dpi, WidgetPreviewLoader previewLoader, IconCache iconCache,
+ private Widget packWidget(int dpi, WidgetPreviewLoader previewLoader, IconCache iconCache,
ComponentName provider) {
final AppWidgetProviderInfo info = findAppWidgetProviderInfo(provider);
Widget widget = new Widget();
@@ -956,16 +923,17 @@ public class LauncherBackupHelper implements BackupHelper {
widget.preview.dpi = dpi;
}
}
- return writeCheckedBytes(widget);
+ return widget;
}
- /** Deserialize a widget from persistence, after verifying checksum wrapper. */
- private Widget unpackWidget(byte[] buffer, int offset, int dataSize)
+ /**
+ * Deserialize a proto after verifying checksum wrapper.
+ */
+ private <T extends MessageNano> T unpackProto(T proto, byte[] buffer, int dataSize)
throws InvalidProtocolBufferNanoException {
- Widget widget = new Widget();
- MessageNano.mergeFrom(widget, readCheckedBytes(buffer, offset, dataSize));
- if (VERBOSE) Log.v(TAG, "unpacked widget " + widget.provider);
- return widget;
+ MessageNano.mergeFrom(proto, readCheckedBytes(buffer, dataSize));
+ if (DEBUG) Log.d(TAG, "unpacked proto " + proto);
+ return proto;
}
/**
@@ -1001,9 +969,6 @@ public class LauncherBackupHelper implements BackupHelper {
if (result > 0) {
availableBytes -= result;
bytesRead += result;
- if (DEBUG && (bytesRead % 100 == 0)) {
- Log.d(TAG, "read some bytes: " + bytesRead);
- }
} else {
Log.w(TAG, "unexpected end of file while reading journal.");
// stop reading and see what there is to parse
@@ -1016,7 +981,7 @@ public class LauncherBackupHelper implements BackupHelper {
// check the buffer to see if we have a valid journal
try {
- MessageNano.mergeFrom(journal, readCheckedBytes(buffer, 0, bytesRead));
+ MessageNano.mergeFrom(journal, readCheckedBytes(buffer, bytesRead));
// if we are here, then we have read a valid, checksum-verified journal
valid = true;
availableBytes = 0;
@@ -1044,46 +1009,17 @@ public class LauncherBackupHelper implements BackupHelper {
return journal;
}
- private void writeRowToBackup(Key key, byte[] blob, Journal out,
+ private void writeRowToBackup(Key key, MessageNano proto, BackupDataOutput data)
+ throws IOException {
+ writeRowToBackup(keyToBackupKey(key), proto, data);
+ }
+
+ private void writeRowToBackup(String backupKey, MessageNano proto,
BackupDataOutput data) throws IOException {
- String backupKey = keyToBackupKey(key);
+ byte[] blob = writeCheckedBytes(proto);
data.writeEntityHeader(backupKey, blob.length);
data.writeEntityData(blob, blob.length);
- out.rows++;
- out.bytes += blob.length;
- if (VERBOSE) Log.v(TAG, "saving " + geKeyType(key) + " " + backupKey + ": " +
- getKeyName(key) + "/" + blob.length);
- if(DEBUG_PAYLOAD) {
- String encoded = Base64.encodeToString(blob, 0, blob.length, Base64.NO_WRAP);
- final int chunkSize = 1024;
- for (int offset = 0; offset < encoded.length(); offset += chunkSize) {
- int end = offset + chunkSize;
- end = Math.min(end, encoded.length());
- Log.w(TAG, "wrote " + encoded.substring(offset, end));
- }
- }
- }
-
- private Set<String> getSavedIdsByType(int type, Journal in) {
- Set<String> savedIds = new HashSet<String>();
- for(int i = 0; i < in.key.length; i++) {
- Key key = in.key[i];
- if (key.type == type) {
- savedIds.add(keyToBackupKey(key));
- }
- }
- return savedIds;
- }
-
- private int removeDeletedKeysFromBackup(Set<String> deletedIds, BackupDataOutput data)
- throws IOException {
- int rows = 0;
- for(String deleted: deletedIds) {
- if (VERBOSE) Log.v(TAG, "dropping deleted item " + deleted);
- data.writeEntityHeader(deleted, -1);
- rows++;
- }
- return rows;
+ if (VERBOSE) Log.v(TAG, "Writing New entry " + backupKey);
}
/**
@@ -1119,10 +1055,10 @@ public class LauncherBackupHelper implements BackupHelper {
}
/** Unwrap a proto message from a CheckedMessage, verifying the checksum. */
- private static byte[] readCheckedBytes(byte[] buffer, int offset, int dataSize)
+ private static byte[] readCheckedBytes(byte[] buffer, int dataSize)
throws InvalidProtocolBufferNanoException {
CheckedMessage wrapper = new CheckedMessage();
- MessageNano.mergeFrom(wrapper, buffer, offset, dataSize);
+ MessageNano.mergeFrom(wrapper, buffer, 0, dataSize);
CRC32 checksum = new CRC32();
checksum.update(wrapper.payload);
if (wrapper.checksum != checksum.getValue()) {
@@ -1161,7 +1097,9 @@ public class LauncherBackupHelper implements BackupHelper {
}
- // check if the launcher is in a state to support backup
+ /**
+ * @return true if the launcher is in a state to support backup
+ */
private boolean launcherIsReady() {
ContentResolver cr = mContext.getContentResolver();
Cursor cursor = cr.query(Favorites.CONTENT_URI, FAVORITE_PROJECTION, null, null, null);
@@ -1185,12 +1123,12 @@ public class LauncherBackupHelper implements BackupHelper {
.getSerialNumberForUser(UserHandleCompat.myUserHandle());
}
- private class KeyParsingException extends Throwable {
- private KeyParsingException(Throwable cause) {
+ private class InvalidBackupException extends IOException {
+ private InvalidBackupException(Throwable cause) {
super(cause);
}
- public KeyParsingException(String reason) {
+ public InvalidBackupException(String reason) {
super(reason);
}
}
diff --git a/src/com/android/launcher3/LauncherCallbacks.java b/src/com/android/launcher3/LauncherCallbacks.java
new file mode 100644
index 000000000..a1f4e0b90
--- /dev/null
+++ b/src/com/android/launcher3/LauncherCallbacks.java
@@ -0,0 +1,108 @@
+package com.android.launcher3;
+
+import android.content.ComponentName;
+import android.content.Intent;
+import android.graphics.Rect;
+import android.os.Bundle;
+import android.view.Menu;
+import android.view.View;
+import android.view.ViewGroup;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+
+/**
+ * LauncherCallbacks is an interface used to extend the Launcher activity. It includes many hooks
+ * in order to add additional functionality. Some of these are very general, and give extending
+ * classes the ability to react to Activity life-cycle or specific user interactions. Others
+ * are more specific and relate to replacing parts of the application, for example, the search
+ * interface or the wallpaper picker.
+ */
+public interface LauncherCallbacks {
+
+ /*
+ * Activity life-cycle methods. These methods are triggered after
+ * the code in the corresponding Launcher method is executed.
+ */
+ public void preOnCreate();
+ public void onCreate(Bundle savedInstanceState);
+ public void preOnResume();
+ public void onResume();
+ public void onStart();
+ public void onStop();
+ public void onPause();
+ public void onDestroy();
+ public void onSaveInstanceState(Bundle outState);
+ public void onPostCreate(Bundle savedInstanceState);
+ public void onNewIntent(Intent intent);
+ public void onActivityResult(int requestCode, int resultCode, Intent data);
+ public void onWindowFocusChanged(boolean hasFocus);
+ public boolean onPrepareOptionsMenu(Menu menu);
+ public void dump(String prefix, FileDescriptor fd, PrintWriter w, String[] args);
+ public void onHomeIntent();
+ public boolean handleBackPressed();
+
+ /*
+ * Extension points for providing custom behavior on certain user interactions.
+ */
+ public void onLauncherProviderChange();
+ public void finishBindingItems(final boolean upgradePath);
+ public void onClickAllAppsButton(View v);
+ public void bindAllApplications(ArrayList<AppInfo> apps);
+ public void onClickFolderIcon(View v);
+ public void onClickAppShortcut(View v);
+ public void onClickPagedViewIcon(View v);
+ public void onClickWallpaperPicker(View v);
+ public void onClickSettingsButton(View v);
+ public void onClickAddWidgetButton(View v);
+ public void onPageSwitch(View newPage, int newPageIndex);
+ public void onWorkspaceLockedChanged();
+ public void onDragStarted(View view);
+ public void onInteractionBegin();
+ public void onInteractionEnd();
+
+ /*
+ * Extension points for replacing the search experience
+ */
+ public boolean forceDisableVoiceButtonProxy();
+ public boolean providesSearch();
+ public boolean startSearch(String initialQuery, boolean selectInitialQuery,
+ Bundle appSearchData, Rect sourceBounds);
+ public void startVoice();
+ public boolean hasCustomContentToLeft();
+ public void populateCustomContentContainer();
+ public View getQsbBar();
+
+ /*
+ * Extensions points for adding / replacing some other aspects of the Launcher experience.
+ */
+ public Intent getFirstRunActivity();
+ public boolean hasFirstRunActivity();
+ public boolean hasDismissableIntroScreen();
+ public View getIntroScreen();
+ public boolean shouldMoveToDefaultScreenOnHomeIntent();
+ public boolean hasSettings();
+ public ComponentName getWallpaperPickerComponent();
+ public boolean overrideWallpaperDimensions();
+ public boolean isLauncherPreinstalled();
+
+ /**
+ * Returning true will immediately result in a call to {@link #setLauncherOverlayView(ViewGroup,
+ * com.android.launcher3.Launcher.LauncherOverlayCallbacks)}.
+ *
+ * @return true if this launcher extension will provide an overlay
+ */
+ public boolean hasLauncherOverlay();
+
+ /**
+ * Handshake to establish an overlay relationship
+ *
+ * @param container Full screen overlay ViewGroup into which custom views can be placed.
+ * @param callbacks A set of callbacks provided by Launcher in relation to the overlay
+ * @return an interface used to make requests and notify the Launcher in relation to the overlay
+ */
+ public Launcher.LauncherOverlay setLauncherOverlayView(InsettableFrameLayout container,
+ Launcher.LauncherOverlayCallbacks callbacks);
+
+}
diff --git a/src/com/android/launcher3/LauncherClings.java b/src/com/android/launcher3/LauncherClings.java
index 458d81f61..ef8e8abcf 100644
--- a/src/com/android/launcher3/LauncherClings.java
+++ b/src/com/android/launcher3/LauncherClings.java
@@ -27,7 +27,6 @@ import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.UserManager;
import android.provider.Settings;
-import android.view.ContextThemeWrapper;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
@@ -56,8 +55,7 @@ class LauncherClings implements OnClickListener {
/** Ctor */
public LauncherClings(Launcher launcher) {
mLauncher = launcher;
- mInflater = LayoutInflater.from(new
- ContextThemeWrapper(mLauncher, android.R.style.Theme_DeviceDefault));
+ mInflater = LayoutInflater.from(mLauncher);
}
@Override
diff --git a/src/com/android/launcher3/LauncherExtension.java b/src/com/android/launcher3/LauncherExtension.java
new file mode 100644
index 000000000..b264042cf
--- /dev/null
+++ b/src/com/android/launcher3/LauncherExtension.java
@@ -0,0 +1,354 @@
+package com.android.launcher3;
+
+import android.animation.Animator;
+import android.animation.Animator.AnimatorListener;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ObjectAnimator;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.graphics.Rect;
+import android.os.Bundle;
+import android.view.Menu;
+import android.view.View;
+import android.view.ViewGroup;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+
+/**
+ * This class represents a very trivial LauncherExtension. It primarily serves as a simple
+ * class to exercise the LauncherOverlay interface.
+ */
+public class LauncherExtension extends Launcher {
+
+ //------ Activity methods -------//
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ setLauncherCallbacks(new LauncherExtensionCallbacks());
+ super.onCreate(savedInstanceState);
+ }
+
+ public class LauncherExtensionCallbacks implements LauncherCallbacks {
+
+ LauncherExtensionOverlay mLauncherOverlay = new LauncherExtensionOverlay();
+
+ @Override
+ public void preOnCreate() {
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ }
+
+ @Override
+ public void preOnResume() {
+ }
+
+ @Override
+ public void onResume() {
+ }
+
+ @Override
+ public void onStart() {
+ }
+
+ @Override
+ public void onStop() {
+ }
+
+ @Override
+ public void onPause() {
+ }
+
+ @Override
+ public void onDestroy() {
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle outState) {
+ }
+
+ @Override
+ public void onPostCreate(Bundle savedInstanceState) {
+ }
+
+ @Override
+ public void onNewIntent(Intent intent) {
+ }
+
+ @Override
+ public void onActivityResult(int requestCode, int resultCode, Intent data) {
+ }
+
+ @Override
+ public void onWindowFocusChanged(boolean hasFocus) {
+ }
+
+ @Override
+ public boolean onPrepareOptionsMenu(Menu menu) {
+ return false;
+ }
+
+ @Override
+ public void dump(String prefix, FileDescriptor fd, PrintWriter w, String[] args) {
+ }
+
+ @Override
+ public void onHomeIntent() {
+ }
+
+ @Override
+ public boolean handleBackPressed() {
+ if (mLauncherOverlay.isOverlayPanelShowing()) {
+ mLauncherOverlay.hideOverlayPanel();
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public void onLauncherProviderChange() {
+ }
+
+ @Override
+ public void finishBindingItems(boolean upgradePath) {
+ }
+
+ @Override
+ public void onClickAllAppsButton(View v) {
+ }
+
+ @Override
+ public void bindAllApplications(ArrayList<AppInfo> apps) {
+ }
+
+ @Override
+ public void onClickFolderIcon(View v) {
+ }
+
+ @Override
+ public void onClickAppShortcut(View v) {
+ }
+
+ @Override
+ public void onClickPagedViewIcon(View v) {
+ }
+
+ @Override
+ public void onClickWallpaperPicker(View v) {
+ }
+
+ @Override
+ public void onClickSettingsButton(View v) {
+ }
+
+ @Override
+ public void onClickAddWidgetButton(View v) {
+ }
+
+ @Override
+ public void onPageSwitch(View newPage, int newPageIndex) {
+ }
+
+ @Override
+ public void onWorkspaceLockedChanged() {
+ }
+
+ @Override
+ public void onDragStarted(View view) {
+ }
+
+ @Override
+ public void onInteractionBegin() {
+ }
+
+ @Override
+ public void onInteractionEnd() {
+ }
+
+ @Override
+ public boolean forceDisableVoiceButtonProxy() {
+ return false;
+ }
+
+ @Override
+ public boolean providesSearch() {
+ return true;
+ }
+
+ @Override
+ public boolean startSearch(String initialQuery, boolean selectInitialQuery,
+ Bundle appSearchData, Rect sourceBounds) {
+ return false;
+ }
+
+ @Override
+ public void startVoice() {
+ }
+
+ @Override
+ public boolean hasCustomContentToLeft() {
+ return false;
+ }
+
+ @Override
+ public void populateCustomContentContainer() {
+ }
+
+ @Override
+ public View getQsbBar() {
+ return mLauncherOverlay.getSearchBox();
+ }
+
+ @Override
+ public Intent getFirstRunActivity() {
+ return null;
+ }
+
+ @Override
+ public boolean hasFirstRunActivity() {
+ return false;
+ }
+
+ @Override
+ public boolean hasDismissableIntroScreen() {
+ return false;
+ }
+
+ @Override
+ public View getIntroScreen() {
+ return null;
+ }
+
+ @Override
+ public boolean shouldMoveToDefaultScreenOnHomeIntent() {
+ return true;
+ }
+
+ @Override
+ public boolean hasSettings() {
+ return false;
+ }
+
+ @Override
+ public ComponentName getWallpaperPickerComponent() {
+ return null;
+ }
+
+ @Override
+ public boolean overrideWallpaperDimensions() {
+ return false;
+ }
+
+ @Override
+ public boolean isLauncherPreinstalled() {
+ return false;
+ }
+
+ @Override
+ public boolean hasLauncherOverlay() {
+ return true;
+ }
+
+ @Override
+ public LauncherOverlay setLauncherOverlayView(InsettableFrameLayout container,
+ LauncherOverlayCallbacks callbacks) {
+
+ mLauncherOverlay.setOverlayCallbacks(callbacks);
+ mLauncherOverlay.setOverlayContainer(container);
+
+ return mLauncherOverlay;
+ }
+
+ class LauncherExtensionOverlay implements LauncherOverlay {
+ LauncherOverlayCallbacks mLauncherOverlayCallbacks;
+ ViewGroup mOverlayView;
+ View mSearchBox;
+ View mSearchOverlay;
+ boolean mShowOverlayFeedback;
+ int mProgress;
+ boolean mOverlayPanelShowing;
+
+ @Override
+ public void onScrollInteractionBegin() {
+ if (mLauncherOverlayCallbacks.canEnterFullImmersion()) {
+ mShowOverlayFeedback = true;
+ updatePanelOffset(0);
+ mSearchOverlay.setVisibility(View.VISIBLE);
+ mSearchOverlay.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+ }
+ }
+
+ @Override
+ public void onScrollChange(int progress, boolean rtl) {
+ mProgress = progress;
+ if (mShowOverlayFeedback) {
+ updatePanelOffset(progress);
+ }
+ }
+
+ private void updatePanelOffset(int progress) {
+ int panelWidth = mSearchOverlay.getMeasuredWidth();
+ int offset = (int) ((progress / 100f) * panelWidth);
+ mSearchOverlay.setTranslationX(- panelWidth + offset);
+ }
+
+ @Override
+ public void onScrollInteractionEnd() {
+ if (mProgress > 25 && mLauncherOverlayCallbacks.enterFullImmersion()) {
+ ObjectAnimator oa = LauncherAnimUtils.ofFloat(mSearchOverlay, "translationX", 0);
+ oa.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator arg0) {
+ mSearchOverlay.setLayerType(View.LAYER_TYPE_NONE, null);
+ }
+ });
+ oa.start();
+ mOverlayPanelShowing = true;
+ mShowOverlayFeedback = false;
+ }
+ }
+
+ @Override
+ public void onScrollSettled() {
+ if (mShowOverlayFeedback) {
+ mSearchOverlay.setVisibility(View.INVISIBLE);
+ mSearchOverlay.setLayerType(View.LAYER_TYPE_NONE, null);
+ }
+ mShowOverlayFeedback = false;
+ mProgress = 0;
+ }
+
+ public void hideOverlayPanel() {
+ mLauncherOverlayCallbacks.exitFullImmersion();
+ mSearchOverlay.setVisibility(View.INVISIBLE);
+ mOverlayPanelShowing = false;
+ }
+
+ public boolean isOverlayPanelShowing() {
+ return mOverlayPanelShowing;
+ }
+
+ @Override
+ public void forceExitFullImmersion() {
+ hideOverlayPanel();
+ }
+
+ public void setOverlayContainer(InsettableFrameLayout container) {
+ mOverlayView = (ViewGroup) getLayoutInflater().inflate(
+ R.layout.launcher_overlay_example, container);
+ mSearchOverlay = mOverlayView.findViewById(R.id.search_overlay);
+ mSearchBox = mOverlayView.findViewById(R.id.search_box);
+ }
+
+ public View getSearchBox() {
+ return mSearchBox;
+ }
+
+ public void setOverlayCallbacks(LauncherOverlayCallbacks callbacks) {
+ mLauncherOverlayCallbacks = callbacks;
+ }
+ };
+ }
+}
diff --git a/src/com/android/launcher3/LauncherFiles.java b/src/com/android/launcher3/LauncherFiles.java
new file mode 100644
index 000000000..fa053650f
--- /dev/null
+++ b/src/com/android/launcher3/LauncherFiles.java
@@ -0,0 +1,40 @@
+package com.android.launcher3;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Central list of files the Launcher writes to the application data directory.
+ *
+ * To add a new Launcher file, create a String constant referring to the filename, and add it to
+ * ALL_FILES, as shown below.
+ */
+public class LauncherFiles {
+
+ private static final String XML = ".xml";
+
+ public static final String DEFAULT_WALLPAPER_THUMBNAIL = "default_thumb2.jpg";
+ public static final String DEFAULT_WALLPAPER_THUMBNAIL_OLD = "default_thumb.jpg";
+ public static final String LAUNCHER_DB = "launcher.db";
+ public static final String LAUNCHER_PREFERENCES = "launcher.preferences";
+ public static final String LAUNCHES_LOG = "launches.log";
+ public static final String SHARED_PREFERENCES_KEY = "com.android.launcher3.prefs";
+ public static final String STATS_LOG = "stats.log";
+ public static final String WALLPAPER_CROP_PREFERENCES_KEY =
+ WallpaperCropActivity.class.getName();
+ public static final String WALLPAPER_IMAGES_DB = "saved_wallpaper_images.db";
+ public static final String WIDGET_PREVIEWS_DB = "widgetpreviews.db";
+
+ public static final List<String> ALL_FILES = Collections.unmodifiableList(Arrays.asList(
+ DEFAULT_WALLPAPER_THUMBNAIL,
+ DEFAULT_WALLPAPER_THUMBNAIL_OLD,
+ LAUNCHER_DB,
+ LAUNCHER_PREFERENCES,
+ LAUNCHES_LOG,
+ SHARED_PREFERENCES_KEY + XML,
+ STATS_LOG,
+ WALLPAPER_CROP_PREFERENCES_KEY + XML,
+ WALLPAPER_IMAGES_DB,
+ WIDGET_PREVIEWS_DB));
+}
diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java
index c64506d80..954887dc3 100644
--- a/src/com/android/launcher3/LauncherModel.java
+++ b/src/com/android/launcher3/LauncherModel.java
@@ -30,6 +30,7 @@ import android.content.Intent;
import android.content.Intent.ShortcutIconResource;
import android.content.IntentFilter;
import android.content.SharedPreferences;
+import android.content.pm.LauncherApps.Callback;
import android.content.pm.PackageManager;
import android.content.pm.ProviderInfo;
import android.content.pm.ResolveInfo;
@@ -75,7 +76,6 @@ import java.util.List;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeMap;
-import java.util.concurrent.atomic.AtomicBoolean;
/**
* Maintains in-memory state of the Launcher. It is expected that there should be only one
@@ -87,6 +87,7 @@ public class LauncherModel extends BroadcastReceiver
static final boolean DEBUG_LOADERS = false;
private static final boolean DEBUG_RECEIVER = false;
private static final boolean REMOVE_UNRESTORED_ICONS = true;
+ private static final boolean ADD_MANAGED_PROFILE_SHORTCUTS = false;
static final String TAG = "Launcher.Model";
@@ -110,6 +111,11 @@ public class LauncherModel extends BroadcastReceiver
private boolean mIsLoaderTaskRunning;
private volatile boolean mFlushingWorkerThread;
+ /**
+ * Maintain a set of packages per user, for which we added a shortcut on the workspace.
+ */
+ private static final String INSTALLED_SHORTCUTS_SET_PREFIX = "installed_shortcuts_set_for_user_";
+
// Specific runnable types that are run on the main thread deferred handler, this allows us to
// clear all queued binding runnables when the Launcher activity is destroyed.
private static final int MAIN_THREAD_NORMAL_RUNNABLE = 0;
@@ -198,11 +204,13 @@ public class LauncherModel extends BroadcastReceiver
ArrayList<ItemInfo> addAnimated,
ArrayList<AppInfo> addedApps);
public void bindAppsUpdated(ArrayList<AppInfo> apps);
- public void bindAppsRestored(ArrayList<AppInfo> apps);
+ public void bindShortcutsChanged(ArrayList<ShortcutInfo> updated,
+ ArrayList<ShortcutInfo> removed, UserHandleCompat user);
+ public void bindWidgetsRestored(ArrayList<LauncherAppWidgetInfo> widgets);
public void updatePackageState(ArrayList<PackageInstallInfo> installInfo);
public void updatePackageBadge(String packageName);
public void bindComponentsRemoved(ArrayList<String> packageNames,
- ArrayList<AppInfo> appInfos, UserHandleCompat user);
+ ArrayList<AppInfo> appInfos, UserHandleCompat user, int reason);
public void bindPackagesUpdated(ArrayList<Object> widgetsAndShortcuts);
public void bindSearchablesChanged();
public boolean isAllAppsButtonRank(int rank);
@@ -341,7 +349,7 @@ public class LauncherModel extends BroadcastReceiver
// Process the updated package state
Runnable r = new Runnable() {
public void run() {
- Callbacks callbacks = mCallbacks != null ? mCallbacks.get() : null;
+ Callbacks callbacks = getCallback();
if (callbacks != null) {
callbacks.updatePackageState(installInfo);
}
@@ -354,7 +362,7 @@ public class LauncherModel extends BroadcastReceiver
// Process the updated package badge
Runnable r = new Runnable() {
public void run() {
- Callbacks callbacks = mCallbacks != null ? mCallbacks.get() : null;
+ Callbacks callbacks = getCallback();
if (callbacks != null) {
callbacks.updatePackageBadge(packageName);
}
@@ -364,7 +372,7 @@ public class LauncherModel extends BroadcastReceiver
}
public void addAppsToAllApps(final Context ctx, final ArrayList<AppInfo> allAppsApps) {
- final Callbacks callbacks = mCallbacks != null ? mCallbacks.get() : null;
+ final Callbacks callbacks = getCallback();
if (allAppsApps == null) {
throw new RuntimeException("allAppsApps must not be null");
@@ -373,32 +381,13 @@ public class LauncherModel extends BroadcastReceiver
return;
}
- final ArrayList<AppInfo> restoredAppsFinal = new ArrayList<AppInfo>();
- Iterator<AppInfo> iter = allAppsApps.iterator();
- while (iter.hasNext()) {
- ItemInfo a = iter.next();
- if (LauncherModel.appWasPromise(ctx, a.getIntent(), a.user)) {
- restoredAppsFinal.add((AppInfo) a);
- }
- }
-
// Process the newly added applications and add them to the database first
Runnable r = new Runnable() {
public void run() {
runOnMainThread(new Runnable() {
public void run() {
- Callbacks cb = mCallbacks != null ? mCallbacks.get() : null;
+ Callbacks cb = getCallback();
if (callbacks == cb && cb != null) {
- if (!restoredAppsFinal.isEmpty()) {
- for (AppInfo info : restoredAppsFinal) {
- final Intent intent = info.getIntent();
- if (intent != null) {
- mIconCache.deletePreloadedIcon(intent.getComponent(),
- info.user);
- }
- }
- callbacks.bindAppsUpdated(restoredAppsFinal);
- }
callbacks.bindAppsAdded(null, null, null, allAppsApps);
}
}
@@ -410,7 +399,7 @@ public class LauncherModel extends BroadcastReceiver
public void addAndBindAddedWorkspaceApps(final Context context,
final ArrayList<ItemInfo> workspaceApps) {
- final Callbacks callbacks = mCallbacks != null ? mCallbacks.get() : null;
+ final Callbacks callbacks = getCallback();
if (workspaceApps == null) {
throw new RuntimeException("workspaceApps and allAppsApps must not be null");
@@ -423,7 +412,6 @@ public class LauncherModel extends BroadcastReceiver
public void run() {
final ArrayList<ItemInfo> addedShortcutsFinal = new ArrayList<ItemInfo>();
final ArrayList<Long> addedWorkspaceScreensFinal = new ArrayList<Long>();
- final ArrayList<AppInfo> restoredAppsFinal = new ArrayList<AppInfo>();
// Get the list of workspace screens. We need to append to this list and
// can not use sBgWorkspaceScreens because loadWorkspace() may not have been
@@ -443,12 +431,7 @@ public class LauncherModel extends BroadcastReceiver
final Intent launchIntent = a.getIntent();
// Short-circuit this logic if the icon exists somewhere on the workspace
- if (LauncherModel.shortcutExists(context, name, launchIntent)) {
- // Only InstallShortcutReceiver sends us shortcutInfos, ignore them
- if (a instanceof AppInfo &&
- LauncherModel.appWasPromise(context, launchIntent, a.user)) {
- restoredAppsFinal.add((AppInfo) a);
- }
+ if (shortcutExists(context, name, launchIntent, a.user)) {
continue;
}
@@ -507,7 +490,7 @@ public class LauncherModel extends BroadcastReceiver
if (!addedShortcutsFinal.isEmpty()) {
runOnMainThread(new Runnable() {
public void run() {
- Callbacks cb = mCallbacks != null ? mCallbacks.get() : null;
+ Callbacks cb = getCallback();
if (callbacks == cb && cb != null) {
final ArrayList<ItemInfo> addAnimated = new ArrayList<ItemInfo>();
final ArrayList<ItemInfo> addNotAnimated = new ArrayList<ItemInfo>();
@@ -524,9 +507,6 @@ public class LauncherModel extends BroadcastReceiver
}
callbacks.bindAppsAdded(addedWorkspaceScreensFinal,
addNotAnimated, addAnimated, null);
- if (!restoredAppsFinal.isEmpty()) {
- callbacks.bindAppsUpdated(restoredAppsFinal);
- }
}
}
});
@@ -870,7 +850,8 @@ public class LauncherModel extends BroadcastReceiver
* Returns true if the shortcuts already exists in the database.
* we identify a shortcut by its title and intent.
*/
- static boolean shortcutExists(Context context, String title, Intent intent) {
+ static boolean shortcutExists(Context context, String title, Intent intent,
+ UserHandleCompat user) {
final ContentResolver cr = context.getContentResolver();
final Intent intentWithPkg, intentWithoutPkg;
@@ -889,27 +870,18 @@ public class LauncherModel extends BroadcastReceiver
intentWithPkg = intent;
intentWithoutPkg = intent;
}
+ String userSerial = Long.toString(UserManagerCompat.getInstance(context)
+ .getSerialNumberForUser(user));
Cursor c = cr.query(LauncherSettings.Favorites.CONTENT_URI,
- new String[] { "title", "intent" }, "title=? and (intent=? or intent=?)",
- new String[] { title, intentWithPkg.toUri(0), intentWithoutPkg.toUri(0) }, null);
- boolean result = false;
+ new String[] { "title", "intent", "profileId" },
+ "title=? and (intent=? or intent=?) and profileId=?",
+ new String[] { title, intentWithPkg.toUri(0), intentWithoutPkg.toUri(0), userSerial },
+ null);
try {
- result = c.moveToFirst();
+ return c.moveToFirst();
} finally {
c.close();
}
- return result;
- }
-
- /**
- * Returns true if the promise shortcuts with the same package name exists on the workspace.
- */
- static boolean appWasPromise(Context context, Intent intent, UserHandleCompat user) {
- final ComponentName component = intent.getComponent();
- if (component == null) {
- return false;
- }
- return !getItemsByPackageName(component.getPackageName(), user).isEmpty();
}
/**
@@ -1111,7 +1083,7 @@ public class LauncherModel extends BroadcastReceiver
* @param context
* @param item
*/
- static void deleteItemsFromDatabase(Context context, final ArrayList<ItemInfo> items) {
+ static void deleteItemsFromDatabase(Context context, final ArrayList<? extends ItemInfo> items) {
final ContentResolver cr = context.getContentResolver();
Runnable r = new Runnable() {
@@ -1322,11 +1294,9 @@ public class LauncherModel extends BroadcastReceiver
mPreviousConfigMcc = currentConfig.mcc;
} else if (SearchManager.INTENT_GLOBAL_SEARCH_ACTIVITY_CHANGED.equals(action) ||
SearchManager.INTENT_ACTION_SEARCHABLES_CHANGED.equals(action)) {
- if (mCallbacks != null) {
- Callbacks callbacks = mCallbacks.get();
- if (callbacks != null) {
- callbacks.bindSearchablesChanged();
- }
+ Callbacks callbacks = getCallback();
+ if (callbacks != null) {
+ callbacks.bindSearchablesChanged();
}
}
}
@@ -1358,13 +1328,11 @@ public class LauncherModel extends BroadcastReceiver
*/
public void startLoaderFromBackground() {
boolean runLoader = false;
- if (mCallbacks != null) {
- Callbacks callbacks = mCallbacks.get();
- if (callbacks != null) {
- // Only actually run the loader if they're not paused.
- if (!callbacks.setLoadOnResume()) {
- runLoader = true;
- }
+ Callbacks callbacks = getCallback();
+ if (callbacks != null) {
+ // Only actually run the loader if they're not paused.
+ if (!callbacks.setLoadOnResume()) {
+ runLoader = true;
}
}
if (runLoader) {
@@ -1758,8 +1726,7 @@ public class LauncherModel extends BroadcastReceiver
}
// check & update map of what's occupied; used to discard overlapping/invalid items
- private boolean checkItemPlacement(HashMap<Long, ItemInfo[][]> occupied, ItemInfo item,
- AtomicBoolean deleteOnInvalidPlacement) {
+ private boolean checkItemPlacement(HashMap<Long, ItemInfo[][]> occupied, ItemInfo item) {
LauncherAppState app = LauncherAppState.getInstance();
DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
final int countX = (int) grid.numColumns;
@@ -1770,7 +1737,6 @@ public class LauncherModel extends BroadcastReceiver
// Return early if we detect that an item is under the hotseat button
if (mCallbacks == null ||
mCallbacks.get().isAllAppsButtonRank((int) item.screenId)) {
- deleteOnInvalidPlacement.set(true);
Log.e(TAG, "Error loading shortcut into hotseat " + item
+ " into position (" + item.screenId + ":" + item.cellX + ","
+ item.cellY + ") occupied by all apps");
@@ -1967,7 +1933,6 @@ public class LauncherModel extends BroadcastReceiver
UserHandleCompat user;
while (!mStopped && c.moveToNext()) {
- AtomicBoolean deleteOnInvalidPlacement = new AtomicBoolean(false);
try {
int itemType = c.getInt(itemTypeIndex);
boolean restored = 0 != c.getInt(restoredIndex);
@@ -1981,6 +1946,7 @@ public class LauncherModel extends BroadcastReceiver
long serialNumber = c.getInt(profileIdIndex);
user = mUserManager.getUserForSerialNumber(serialNumber);
int promiseType = c.getInt(restoredIndex);
+ int disabledState = 0;
if (user == null) {
// User has been deleted remove the item.
itemsToRemove.add(id);
@@ -2054,14 +2020,13 @@ public class LauncherModel extends BroadcastReceiver
itemsToRemove.add(id);
continue;
}
- } else if (isSdCardReady) {
- // Do not wait for external media load anymore.
- // Log the invalid package, and remove it
- Launcher.addDumpLog(TAG,
- "Invalid package removed: " + cn, true);
- itemsToRemove.add(id);
- continue;
- } else {
+ } else if (launcherApps.isAppEnabled(
+ manager, cn.getPackageName(),
+ PackageManager.GET_UNINSTALLED_PACKAGES)) {
+ // Package is present but not available.
+ allowMissingTarget = true;
+ disabledState = ShortcutInfo.FLAG_DISABLED_NOT_AVAILABLE;
+ } else if (!isSdCardReady) {
// SdCard is not ready yet. Package might get available,
// once it is ready.
Launcher.addDumpLog(TAG, "Invalid package: " + cn
@@ -2074,6 +2039,14 @@ public class LauncherModel extends BroadcastReceiver
pkgs.add(cn.getPackageName());
allowMissingTarget = true;
// Add the icon on the workspace anyway.
+
+ } else {
+ // Do not wait for external media load anymore.
+ // Log the invalid package, and remove it
+ Launcher.addDumpLog(TAG,
+ "Invalid package removed: " + cn, true);
+ itemsToRemove.add(id);
+ continue;
}
} else if (cn == null) {
// For shortcuts with no component, keep them as they are
@@ -2131,15 +2104,14 @@ public class LauncherModel extends BroadcastReceiver
info.spanX = 1;
info.spanY = 1;
info.intent.putExtra(ItemInfo.EXTRA_PROFILE, serialNumber);
- info.isDisabled = isSafeMode
- && !Utilities.isSystemApp(context, intent);
+ info.isDisabled = disabledState;
+ if (isSafeMode && !Utilities.isSystemApp(context, intent)) {
+ info.isDisabled |= ShortcutInfo.FLAG_DISABLED_SAFEMODE;
+ }
// check & update map of what's occupied
- deleteOnInvalidPlacement.set(false);
- if (!checkItemPlacement(occupied, info, deleteOnInvalidPlacement)) {
- if (deleteOnInvalidPlacement.get()) {
- itemsToRemove.add(id);
- }
+ if (!checkItemPlacement(occupied, info)) {
+ itemsToRemove.add(id);
break;
}
@@ -2180,12 +2152,8 @@ public class LauncherModel extends BroadcastReceiver
folderInfo.spanY = 1;
// check & update map of what's occupied
- deleteOnInvalidPlacement.set(false);
- if (!checkItemPlacement(occupied, folderInfo,
- deleteOnInvalidPlacement)) {
- if (deleteOnInvalidPlacement.get()) {
- itemsToRemove.add(id);
- }
+ if (!checkItemPlacement(occupied, folderInfo)) {
+ itemsToRemove.add(id);
break;
}
@@ -2268,7 +2236,7 @@ public class LauncherModel extends BroadcastReceiver
// App restore has started. Update the flag
appWidgetInfo.restoreStatus |=
LauncherAppWidgetInfo.FLAG_RESTORE_STARTED;
- } else if (REMOVE_UNRESTORED_ICONS) {
+ } else if (REMOVE_UNRESTORED_ICONS && !isSafeMode) {
Launcher.addDumpLog(TAG,
"Unrestored widget removed: " + component, true);
itemsToRemove.add(id);
@@ -2293,12 +2261,8 @@ public class LauncherModel extends BroadcastReceiver
appWidgetInfo.container = c.getInt(containerIndex);
// check & update map of what's occupied
- deleteOnInvalidPlacement.set(false);
- if (!checkItemPlacement(occupied, appWidgetInfo,
- deleteOnInvalidPlacement)) {
- if (deleteOnInvalidPlacement.get()) {
- itemsToRemove.add(id);
- }
+ if (!checkItemPlacement(occupied, appWidgetInfo)) {
+ itemsToRemove.add(id);
break;
}
@@ -2852,6 +2816,8 @@ public class LauncherModel extends BroadcastReceiver
// Clear the list of apps
mBgAllAppsList.clear();
+ SharedPreferences prefs = mContext.getSharedPreferences(
+ LauncherAppState.getSharedPreferencesKey(), Context.MODE_PRIVATE);
for (UserHandleCompat user : profiles) {
// Query for the set of apps
final long qiaTime = DEBUG_LOADERS ? SystemClock.uptimeMillis() : 0;
@@ -2862,6 +2828,7 @@ public class LauncherModel extends BroadcastReceiver
Log.d(TAG, "getActivityList got " + apps.size() + " apps for user " + user);
}
// Fail if we don't have any apps
+ // TODO: Fix this. Only fail for the current user.
if (apps == null || apps.isEmpty()) {
return;
}
@@ -2880,6 +2847,25 @@ public class LauncherModel extends BroadcastReceiver
// This builds the icon bitmaps.
mBgAllAppsList.add(new AppInfo(mContext, app, user, mIconCache, mLabelCache));
}
+
+ if (ADD_MANAGED_PROFILE_SHORTCUTS && !user.equals(UserHandleCompat.myUserHandle())) {
+ // Add shortcuts for packages which were installed while launcher was dead.
+ String shortcutsSetKey = INSTALLED_SHORTCUTS_SET_PREFIX
+ + mUserManager.getSerialNumberForUser(user);
+ Set<String> packagesAdded = prefs.getStringSet(shortcutsSetKey, Collections.EMPTY_SET);
+ HashSet<String> newPackageSet = new HashSet<String>();
+
+ for (LauncherActivityInfoCompat info : apps) {
+ String packageName = info.getComponentName().getPackageName();
+ if (!packagesAdded.contains(packageName)
+ && !newPackageSet.contains(packageName)) {
+ InstallShortcutReceiver.queueInstallShortcut(info, mContext);
+ }
+ newPackageSet.add(packageName);
+ }
+
+ prefs.edit().putStringSet(shortcutsSetKey, newPackageSet).commit();
+ }
}
// Huh? Shouldn't this be inside the Runnable below?
final ArrayList<AppInfo> added = mBgAllAppsList.added;
@@ -2930,84 +2916,40 @@ public class LauncherModel extends BroadcastReceiver
synchronized (sBgLock) {
final LauncherAppsCompat launcherApps = LauncherAppsCompat
.getInstance(mApp.getContext());
- ArrayList<String> packagesRemoved;
+ final PackageManager manager = context.getPackageManager();
+ final ArrayList<String> packagesRemoved = new ArrayList<String>();
+ final ArrayList<String> packagesUnavailable = new ArrayList<String>();
for (Entry<UserHandleCompat, HashSet<String>> entry : sPendingPackages.entrySet()) {
UserHandleCompat user = entry.getKey();
- packagesRemoved = new ArrayList<String>();
+ packagesRemoved.clear();
+ packagesUnavailable.clear();
for (String pkg : entry.getValue()) {
if (!launcherApps.isPackageEnabledForProfile(pkg, user)) {
- Launcher.addDumpLog(TAG, "Package not found: " + pkg, true);
- packagesRemoved.add(pkg);
+ boolean packageOnSdcard = launcherApps.isAppEnabled(
+ manager, pkg, PackageManager.GET_UNINSTALLED_PACKAGES);
+ if (packageOnSdcard) {
+ Launcher.addDumpLog(TAG, "Package found on sd-card: " + pkg, true);
+ packagesUnavailable.add(pkg);
+ } else {
+ Launcher.addDumpLog(TAG, "Package not found: " + pkg, true);
+ packagesRemoved.add(pkg);
+ }
}
}
if (!packagesRemoved.isEmpty()) {
enqueuePackageUpdated(new PackageUpdatedTask(PackageUpdatedTask.OP_REMOVE,
packagesRemoved.toArray(new String[packagesRemoved.size()]), user));
}
+ if (!packagesUnavailable.isEmpty()) {
+ enqueuePackageUpdated(new PackageUpdatedTask(PackageUpdatedTask.OP_UNAVAILABLE,
+ packagesUnavailable.toArray(new String[packagesUnavailable.size()]), user));
+ }
}
sPendingPackages.clear();
}
}
}
- /**
- * Workaround to re-check unrestored items, in-case they were installed but the Package-ADD
- * runnable was missed by the launcher.
- */
- public void recheckRestoredItems(final Context context) {
- Runnable r = new Runnable() {
-
- @Override
- public void run() {
- LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(context);
- HashSet<String> installedPackages = new HashSet<String>();
- UserHandleCompat user = UserHandleCompat.myUserHandle();
- synchronized(sBgLock) {
- for (ItemInfo info : sBgItemsIdMap.values()) {
- if (info instanceof ShortcutInfo) {
- ShortcutInfo si = (ShortcutInfo) info;
- if (si.isPromise() && si.getTargetComponent() != null
- && launcherApps.isPackageEnabledForProfile(
- si.getTargetComponent().getPackageName(), user)) {
- installedPackages.add(si.getTargetComponent().getPackageName());
- }
- } else if (info instanceof LauncherAppWidgetInfo) {
- LauncherAppWidgetInfo widget = (LauncherAppWidgetInfo) info;
- if (widget.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY)
- && launcherApps.isPackageEnabledForProfile(
- widget.providerName.getPackageName(), user)) {
- installedPackages.add(widget.providerName.getPackageName());
- }
- }
- }
- }
-
- if (!installedPackages.isEmpty()) {
- final ArrayList<AppInfo> restoredApps = new ArrayList<AppInfo>();
- for (String pkg : installedPackages) {
- for (LauncherActivityInfoCompat info : launcherApps.getActivityList(pkg, user)) {
- restoredApps.add(new AppInfo(context, info, user, mIconCache, null));
- }
- }
-
- final Callbacks callbacks = mCallbacks != null ? mCallbacks.get() : null;
- if (!restoredApps.isEmpty()) {
- mHandler.post(new Runnable() {
- public void run() {
- Callbacks cb = mCallbacks != null ? mCallbacks.get() : null;
- if (callbacks == cb && cb != null) {
- callbacks.bindAppsRestored(restoredApps);
- }
- }
- });
- }
-
- }
- }
- };
- sWorker.post(r);
- }
-
private class PackageUpdatedTask implements Runnable {
int mOp;
String[] mPackages;
@@ -3038,6 +2980,31 @@ public class LauncherModel extends BroadcastReceiver
mIconCache.remove(packages[i], mUser);
mBgAllAppsList.addPackage(context, packages[i], mUser);
}
+
+ // Auto add shortcuts for added packages.
+ if (ADD_MANAGED_PROFILE_SHORTCUTS
+ && !UserHandleCompat.myUserHandle().equals(mUser)) {
+ SharedPreferences prefs = context.getSharedPreferences(
+ LauncherAppState.getSharedPreferencesKey(), Context.MODE_PRIVATE);
+ String shortcutsSetKey = INSTALLED_SHORTCUTS_SET_PREFIX
+ + mUserManager.getSerialNumberForUser(mUser);
+ Set<String> shortcutSet = new HashSet<String>(
+ prefs.getStringSet(shortcutsSetKey,Collections.EMPTY_SET));
+
+ for (int i=0; i<N; i++) {
+ if (!shortcutSet.contains(packages[i])) {
+ shortcutSet.add(packages[i]);
+ List<LauncherActivityInfoCompat> activities =
+ mLauncherApps.getActivityList(packages[i], mUser);
+ if (activities != null && !activities.isEmpty()) {
+ InstallShortcutReceiver.queueInstallShortcut(
+ activities.get(0), context);
+ }
+ }
+ }
+
+ prefs.edit().putStringSet(shortcutsSetKey, shortcutSet).commit();
+ }
break;
case OP_UPDATE:
for (int i=0; i<N; i++) {
@@ -3048,10 +3015,25 @@ public class LauncherModel extends BroadcastReceiver
}
break;
case OP_REMOVE:
+ // Remove the packageName for the set of auto-installed shortcuts. This
+ // will ensure that the shortcut when the app is installed again.
+ if (ADD_MANAGED_PROFILE_SHORTCUTS
+ && !UserHandleCompat.myUserHandle().equals(mUser)) {
+ SharedPreferences prefs = context.getSharedPreferences(
+ LauncherAppState.getSharedPreferencesKey(), Context.MODE_PRIVATE);
+ String shortcutsSetKey = INSTALLED_SHORTCUTS_SET_PREFIX
+ + mUserManager.getSerialNumberForUser(mUser);
+ HashSet<String> shortcutSet = new HashSet<String>(
+ prefs.getStringSet(shortcutsSetKey, Collections.EMPTY_SET));
+ shortcutSet.removeAll(Arrays.asList(mPackages));
+ prefs.edit().putStringSet(shortcutsSetKey, shortcutSet).commit();
+ }
+ // Fall through
case OP_UNAVAILABLE:
+ boolean clearCache = mOp == OP_REMOVE;
for (int i=0; i<N; i++) {
if (DEBUG_LOADERS) Log.d(TAG, "mAllAppsList.removePackage " + packages[i]);
- mBgAllAppsList.removePackage(packages[i], mUser);
+ mBgAllAppsList.removePackage(packages[i], mUser, clearCache);
WidgetPreviewLoader.removePackageFromDb(
mApp.getWidgetPreviewCacheDb(), packages[i]);
}
@@ -3075,12 +3057,15 @@ public class LauncherModel extends BroadcastReceiver
mBgAllAppsList.removed.clear();
}
- final Callbacks callbacks = mCallbacks != null ? mCallbacks.get() : null;
+ final Callbacks callbacks = getCallback();
if (callbacks == null) {
Log.w(TAG, "Nobody to tell about the new app. Launcher is probably loading.");
return;
}
+ final HashMap<ComponentName, AppInfo> addedOrUpdatedApps =
+ new HashMap<ComponentName, AppInfo>();
+
if (added != null) {
// Ensure that we add all the workspace applications to the db
if (LauncherAppState.isDisableAllApps()) {
@@ -3089,28 +3074,20 @@ public class LauncherModel extends BroadcastReceiver
} else {
addAppsToAllApps(context, added);
}
+ for (AppInfo ai : added) {
+ addedOrUpdatedApps.put(ai.componentName, ai);
+ }
}
if (modified != null) {
final ArrayList<AppInfo> modifiedFinal = modified;
-
- // Update the launcher db to reflect the changes
- for (AppInfo a : modifiedFinal) {
- ArrayList<ItemInfo> infos =
- getItemInfoForComponentName(a.componentName, mUser);
- for (ItemInfo i : infos) {
- if (isShortcutInfoUpdateable(i)) {
- ShortcutInfo info = (ShortcutInfo) i;
- info.title = a.title.toString();
- info.contentDescription = a.contentDescription;
- updateItemInDatabase(context, info);
- }
- }
+ for (AppInfo ai : modified) {
+ addedOrUpdatedApps.put(ai.componentName, ai);
}
mHandler.post(new Runnable() {
public void run() {
- Callbacks cb = mCallbacks != null ? mCallbacks.get() : null;
+ Callbacks cb = getCallback();
if (callbacks == cb && cb != null) {
callbacks.bindAppsUpdated(modifiedFinal);
}
@@ -3118,41 +3095,174 @@ public class LauncherModel extends BroadcastReceiver
});
}
+ // Update shortcut infos
+ if (mOp == OP_ADD || mOp == OP_UPDATE) {
+ final ArrayList<ShortcutInfo> updatedShortcuts = new ArrayList<ShortcutInfo>();
+ final ArrayList<ShortcutInfo> removedShortcuts = new ArrayList<ShortcutInfo>();
+ final ArrayList<LauncherAppWidgetInfo> widgets = new ArrayList<LauncherAppWidgetInfo>();
+
+ HashSet<String> packageSet = new HashSet<String>(Arrays.asList(packages));
+ synchronized (sBgLock) {
+ for (ItemInfo info : sBgItemsIdMap.values()) {
+ if (info instanceof ShortcutInfo && mUser.equals(info.user)) {
+ ShortcutInfo si = (ShortcutInfo) info;
+ boolean infoUpdated = false;
+ boolean shortcutUpdated = false;
+
+ // Update shortcuts which use iconResource.
+ if ((si.iconResource != null)
+ && packageSet.contains(si.iconResource.packageName)) {
+ Bitmap icon = Utilities.createIconBitmap(si.iconResource.packageName,
+ si.iconResource.resourceName, mIconCache, context);
+ if (icon != null) {
+ si.setIcon(icon);
+ si.usingFallbackIcon = false;
+ infoUpdated = true;
+ }
+ }
+
+ ComponentName cn = si.getTargetComponent();
+ if (cn != null && packageSet.contains(cn.getPackageName())) {
+ AppInfo appInfo = addedOrUpdatedApps.get(cn);
+
+ if (si.isPromise()) {
+ mIconCache.deletePreloadedIcon(cn, mUser);
+ if (si.hasStatusFlag(ShortcutInfo.FLAG_AUTOINTALL_ICON)) {
+ // Auto install icon
+ PackageManager pm = context.getPackageManager();
+ ResolveInfo matched = pm.resolveActivity(
+ new Intent(Intent.ACTION_MAIN)
+ .setComponent(cn).addCategory(Intent.CATEGORY_LAUNCHER),
+ PackageManager.MATCH_DEFAULT_ONLY);
+ if (matched == null) {
+ // Try to find the best match activity.
+ Intent intent = pm.getLaunchIntentForPackage(
+ cn.getPackageName());
+ if (intent != null) {
+ cn = intent.getComponent();
+ appInfo = addedOrUpdatedApps.get(cn);
+ }
+
+ if ((intent == null) || (appInfo == null)) {
+ removedShortcuts.add(si);
+ continue;
+ }
+ si.promisedIntent = intent;
+ }
+ }
+
+ // Restore the shortcut.
+ si.intent = si.promisedIntent;
+ si.promisedIntent = null;
+ si.status &= ~ShortcutInfo.FLAG_RESTORED_ICON
+ & ~ShortcutInfo.FLAG_AUTOINTALL_ICON
+ & ~ShortcutInfo.FLAG_INSTALL_SESSION_ACTIVE;
+
+ infoUpdated = true;
+ si.updateIcon(mIconCache);
+ }
+
+ if (appInfo != null && Intent.ACTION_MAIN.equals(si.intent.getAction())
+ && si.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) {
+ si.updateIcon(mIconCache);
+ si.title = appInfo.title.toString();
+ si.contentDescription = appInfo.contentDescription;
+ infoUpdated = true;
+ }
+
+ if ((si.isDisabled & ShortcutInfo.FLAG_DISABLED_NOT_AVAILABLE) != 0) {
+ // Since package was just updated, the target must be available now.
+ si.isDisabled &= ~ShortcutInfo.FLAG_DISABLED_NOT_AVAILABLE;
+ shortcutUpdated = true;
+ }
+ }
+
+ if (infoUpdated || shortcutUpdated) {
+ updatedShortcuts.add(si);
+ }
+ if (infoUpdated) {
+ updateItemInDatabase(context, si);
+ }
+ } else if (info instanceof LauncherAppWidgetInfo) {
+ LauncherAppWidgetInfo widgetInfo = (LauncherAppWidgetInfo) info;
+ if (mUser.equals(widgetInfo.user)
+ && widgetInfo.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY)
+ && packageSet.contains(widgetInfo.providerName.getPackageName())) {
+ widgetInfo.restoreStatus &= ~LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY;
+ widgets.add(widgetInfo);
+ updateItemInDatabase(context, widgetInfo);
+ }
+ }
+ }
+ }
+
+ if (!updatedShortcuts.isEmpty() || !removedShortcuts.isEmpty()) {
+ mHandler.post(new Runnable() {
+
+ public void run() {
+ Callbacks cb = getCallback();
+ if (callbacks == cb && cb != null) {
+ callbacks.bindShortcutsChanged(
+ updatedShortcuts, removedShortcuts, mUser);
+ }
+ }
+ });
+ if (!removedShortcuts.isEmpty()) {
+ deleteItemsFromDatabase(context, removedShortcuts);
+ }
+ }
+ if (!widgets.isEmpty()) {
+ mHandler.post(new Runnable() {
+ public void run() {
+ Callbacks cb = getCallback();
+ if (callbacks == cb && cb != null) {
+ callbacks.bindWidgetsRestored(widgets);
+ }
+ }
+ });
+ }
+ }
+
final ArrayList<String> removedPackageNames =
new ArrayList<String>();
- if (mOp == OP_REMOVE) {
+ if (mOp == OP_REMOVE || mOp == OP_UNAVAILABLE) {
// Mark all packages in the broadcast to be removed
removedPackageNames.addAll(Arrays.asList(packages));
} else if (mOp == OP_UPDATE) {
// Mark disabled packages in the broadcast to be removed
- final PackageManager pm = context.getPackageManager();
for (int i=0; i<N; i++) {
if (isPackageDisabled(context, packages[i], mUser)) {
removedPackageNames.add(packages[i]);
}
}
}
- // Remove all the components associated with this package
- for (String pn : removedPackageNames) {
- deletePackageFromDatabase(context, pn, mUser);
- }
- // Remove all the specific components
- for (AppInfo a : removedApps) {
- ArrayList<ItemInfo> infos = getItemInfoForComponentName(a.componentName, mUser);
- deleteItemsFromDatabase(context, infos);
- }
+
if (!removedPackageNames.isEmpty() || !removedApps.isEmpty()) {
+ final int removeReason;
+ if (mOp == OP_UNAVAILABLE) {
+ removeReason = ShortcutInfo.FLAG_DISABLED_NOT_AVAILABLE;
+ } else {
+ // Remove all the components associated with this package
+ for (String pn : removedPackageNames) {
+ deletePackageFromDatabase(context, pn, mUser);
+ }
+ // Remove all the specific components
+ for (AppInfo a : removedApps) {
+ ArrayList<ItemInfo> infos = getItemInfoForComponentName(a.componentName, mUser);
+ deleteItemsFromDatabase(context, infos);
+ }
+ removeReason = 0;
+ }
+
// Remove any queued items from the install queue
- String spKey = LauncherAppState.getSharedPreferencesKey();
- SharedPreferences sp =
- context.getSharedPreferences(spKey, Context.MODE_PRIVATE);
- InstallShortcutReceiver.removeFromInstallQueue(sp, removedPackageNames);
+ InstallShortcutReceiver.removeFromInstallQueue(context, removedPackageNames, mUser);
// Call the components-removed callback
mHandler.post(new Runnable() {
public void run() {
- Callbacks cb = mCallbacks != null ? mCallbacks.get() : null;
+ Callbacks cb = getCallback();
if (callbacks == cb && cb != null) {
- callbacks.bindComponentsRemoved(removedPackageNames, removedApps, mUser);
+ callbacks.bindComponentsRemoved(
+ removedPackageNames, removedApps, mUser, removeReason);
}
}
});
@@ -3163,7 +3273,7 @@ public class LauncherModel extends BroadcastReceiver
mHandler.post(new Runnable() {
@Override
public void run() {
- Callbacks cb = mCallbacks != null ? mCallbacks.get() : null;
+ Callbacks cb = getCallback();
if (callbacks == cb && cb != null) {
callbacks.bindPackagesUpdated(widgetsAndShortcuts);
}
@@ -3173,7 +3283,7 @@ public class LauncherModel extends BroadcastReceiver
// Write all the logs to disk
mHandler.post(new Runnable() {
public void run() {
- Callbacks cb = mCallbacks != null ? mCallbacks.get() : null;
+ Callbacks cb = getCallback();
if (callbacks == cb && cb != null) {
callbacks.dumpLogsToLocalData();
}
@@ -3402,26 +3512,6 @@ public class LauncherModel extends BroadcastReceiver
return filterItemInfos(sBgItemsIdMap.values(), filter);
}
- public static boolean isShortcutInfoUpdateable(ItemInfo i) {
- if (i instanceof ShortcutInfo) {
- ShortcutInfo info = (ShortcutInfo) i;
- // We need to check for ACTION_MAIN otherwise getComponent() might
- // return null for some shortcuts (for instance, for shortcuts to
- // web pages.)
- Intent intent = info.intent;
- ComponentName name = intent.getComponent();
- if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION &&
- Intent.ACTION_MAIN.equals(intent.getAction()) && name != null) {
- return true;
- }
- // placeholder shortcuts get special treatment, let them through too.
- if (info.isPromise()) {
- return true;
- }
- }
- return false;
- }
-
/**
* Make an ShortcutInfo object for a shortcut that isn't an application.
*/
@@ -3444,19 +3534,9 @@ public class LauncherModel extends BroadcastReceiver
case LauncherSettings.Favorites.ICON_TYPE_RESOURCE:
String packageName = c.getString(iconPackageIndex);
String resourceName = c.getString(iconResourceIndex);
- PackageManager packageManager = context.getPackageManager();
info.customIcon = false;
// the resource
- try {
- Resources resources = packageManager.getResourcesForApplication(packageName);
- if (resources != null) {
- final int id = resources.getIdentifier(resourceName, null, null);
- icon = Utilities.createIconBitmap(
- mIconCache.getFullResIcon(resources, id), context);
- }
- } catch (Exception e) {
- // drop this. we have other places to look for icons
- }
+ icon = Utilities.createIconBitmap(packageName, resourceName, mIconCache, context);
// the db
if (icon == null) {
icon = getIconFromCursor(c, iconIndex, context);
@@ -3503,17 +3583,6 @@ public class LauncherModel extends BroadcastReceiver
}
}
- ShortcutInfo addShortcut(Context context, Intent data, long container, int screen,
- int cellX, int cellY, boolean notify) {
- final ShortcutInfo info = infoFromShortcutIntent(context, data, null);
- if (info == null) {
- return null;
- }
- addItemToDatabase(context, info, container, screen, cellX, cellY, notify);
-
- return info;
- }
-
/**
* Attempts to find an AppWidgetProviderInfo that matches the given component.
*/
@@ -3529,7 +3598,7 @@ public class LauncherModel extends BroadcastReceiver
return null;
}
- ShortcutInfo infoFromShortcutIntent(Context context, Intent data, Bitmap fallbackIcon) {
+ ShortcutInfo infoFromShortcutIntent(Context context, Intent data) {
Intent intent = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT);
String name = data.getStringExtra(Intent.EXTRA_SHORTCUT_NAME);
Parcelable bitmap = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_ICON);
@@ -3544,24 +3613,15 @@ public class LauncherModel extends BroadcastReceiver
boolean customIcon = false;
ShortcutIconResource iconResource = null;
- if (bitmap != null && bitmap instanceof Bitmap) {
- icon = Utilities.createIconBitmap(new FastBitmapDrawable((Bitmap)bitmap), context);
+ if (bitmap instanceof Bitmap) {
+ icon = Utilities.createIconBitmap((Bitmap) bitmap, context);
customIcon = true;
} else {
Parcelable extra = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE);
- if (extra != null && extra instanceof ShortcutIconResource) {
- try {
- iconResource = (ShortcutIconResource) extra;
- final PackageManager packageManager = context.getPackageManager();
- Resources resources = packageManager.getResourcesForApplication(
- iconResource.packageName);
- final int id = resources.getIdentifier(iconResource.resourceName, null, null);
- icon = Utilities.createIconBitmap(
- mIconCache.getFullResIcon(resources, id),
- context);
- } catch (Exception e) {
- Log.w(TAG, "Could not load shortcut icon: " + extra);
- }
+ if (extra instanceof ShortcutIconResource) {
+ iconResource = (ShortcutIconResource) extra;
+ icon = Utilities.createIconBitmap(iconResource.packageName,
+ iconResource.resourceName, mIconCache, context);
}
}
@@ -3571,12 +3631,8 @@ public class LauncherModel extends BroadcastReceiver
// users wouldn't get here without intent forwarding anyway.
info.user = UserHandleCompat.myUserHandle();
if (icon == null) {
- if (fallbackIcon != null) {
- icon = fallbackIcon;
- } else {
- icon = mIconCache.getDefaultIcon(info.user);
- info.usingFallbackIcon = true;
- }
+ icon = mIconCache.getDefaultIcon(info.user);
+ info.usingFallbackIcon = true;
}
info.setIcon(icon);
@@ -3761,4 +3817,8 @@ public class LauncherModel extends BroadcastReceiver
Log.d(TAG, "mLoaderTask=null");
}
}
+
+ public Callbacks getCallback() {
+ return mCallbacks != null ? mCallbacks.get() : null;
+ }
}
diff --git a/src/com/android/launcher3/LauncherPreferencesBackupHelper.java b/src/com/android/launcher3/LauncherPreferencesBackupHelper.java
deleted file mode 100644
index 6f9c05c88..000000000
--- a/src/com/android/launcher3/LauncherPreferencesBackupHelper.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2014 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.launcher3;
-
-import android.app.backup.BackupDataInputStream;
-import android.app.backup.SharedPreferencesBackupHelper;
-import android.content.Context;
-import android.util.Log;
-
-public class LauncherPreferencesBackupHelper extends SharedPreferencesBackupHelper {
-
- private static final String TAG = "LauncherPreferencesBackupHelper";
- private static final boolean VERBOSE = LauncherBackupAgentHelper.VERBOSE;
-
- private final boolean mRestoreEnabled;
-
- public LauncherPreferencesBackupHelper(Context context, String sharedPreferencesKey,
- boolean restoreEnabled) {
- super(context, sharedPreferencesKey);
- mRestoreEnabled = restoreEnabled;
- }
-
- @Override
- public void restoreEntity(BackupDataInputStream data) {
- if (mRestoreEnabled) {
- if (VERBOSE) Log.v(TAG, "restoring preferences");
- super.restoreEntity(data);
- }
- }
-}
diff --git a/src/com/android/launcher3/LauncherProvider.java b/src/com/android/launcher3/LauncherProvider.java
index 6cc1688de..1715b02bf 100644
--- a/src/com/android/launcher3/LauncherProvider.java
+++ b/src/com/android/launcher3/LauncherProvider.java
@@ -16,7 +16,6 @@
package com.android.launcher3;
-import android.app.SearchManager;
import android.appwidget.AppWidgetHost;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProviderInfo;
@@ -31,12 +30,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.OperationApplicationException;
import android.content.SharedPreferences;
-import android.content.pm.ActivityInfo;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
import android.content.res.Resources;
-import android.content.res.XmlResourceParser;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
@@ -46,7 +40,6 @@ import android.database.sqlite.SQLiteStatement;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
-import android.os.Bundle;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;
@@ -58,23 +51,16 @@ import com.android.launcher3.compat.UserHandleCompat;
import com.android.launcher3.compat.UserManagerCompat;
import com.android.launcher3.config.ProviderConfig;
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
import java.io.File;
-import java.io.IOException;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
-import java.util.List;
public class LauncherProvider extends ContentProvider {
private static final String TAG = "Launcher.LauncherProvider";
private static final boolean LOGD = false;
- private static final String DATABASE_NAME = "launcher.db";
-
private static final int DATABASE_VERSION = 20;
static final String OLD_AUTHORITY = "com.android.launcher2.settings";
@@ -91,9 +77,6 @@ public class LauncherProvider extends ContentProvider {
static final String EMPTY_DATABASE_CREATED =
"EMPTY_DATABASE_CREATED";
- private static final String ACTION_APPWIDGET_DEFAULT_WORKSPACE_CONFIGURE =
- "com.android.launcher.action.APPWIDGET_DEFAULT_WORKSPACE_CONFIGURE";
-
private static final String URI_PARAM_IS_EXTERNAL_ADD = "isExternalAdd";
private LauncherProviderChangeListener mListener;
@@ -162,12 +145,6 @@ public class LauncherProvider extends ContentProvider {
return db.insert(table, nullColumnHack, values);
}
- private static void deleteId(SQLiteDatabase db, long id) {
- Uri uri = LauncherSettings.Favorites.getContentUri(id, false);
- SqlArguments args = new SqlArguments(uri, null, null);
- db.delete(args.table, args.where, args.args);
- }
-
@Override
public Uri insert(Uri uri, ContentValues initialValues) {
SqlArguments args = new SqlArguments(uri);
@@ -314,6 +291,14 @@ public class LauncherProvider extends ContentProvider {
mOpenHelper.createEmptyDB(mOpenHelper.getWritableDatabase());
}
+ public void clearFlagEmptyDbCreated() {
+ String spKey = LauncherAppState.getSharedPreferencesKey();
+ getContext().getSharedPreferences(spKey, Context.MODE_PRIVATE)
+ .edit()
+ .remove(EMPTY_DATABASE_CREATED)
+ .commit();
+ }
+
/**
* Loads the default workspace based on the following priority scheme:
* 1) From a package provided by play store
@@ -327,7 +312,7 @@ public class LauncherProvider extends ContentProvider {
if (sp.getBoolean(EMPTY_DATABASE_CREATED, false)) {
Log.d(TAG, "loading default workspace");
- WorkspaceLoader loader = AutoInstallsLayout.get(getContext(),
+ AutoInstallsLayout loader = AutoInstallsLayout.get(getContext(),
mOpenHelper.mAppWidgetHost, mOpenHelper);
if (loader == null) {
@@ -337,38 +322,40 @@ public class LauncherProvider extends ContentProvider {
int workspaceResId = partnerRes.getIdentifier(Partner.RES_DEFAULT_LAYOUT,
"xml", partner.getPackageName());
if (workspaceResId != 0) {
- loader = new SimpleWorkspaceLoader(mOpenHelper, partnerRes, workspaceResId);
+ loader = new DefaultLayoutParser(getContext(), mOpenHelper.mAppWidgetHost,
+ mOpenHelper, partnerRes, workspaceResId);
}
}
}
+ final boolean usingExternallyProvidedLayout = loader != null;
if (loader == null) {
- loader = new SimpleWorkspaceLoader(mOpenHelper, getContext().getResources(),
- getDefaultWorkspaceResourceId());
+ loader = getDefaultLayoutParser();
}
-
// Populate favorites table with initial favorites
- SharedPreferences.Editor editor = sp.edit().remove(EMPTY_DATABASE_CREATED);
- mOpenHelper.loadFavorites(mOpenHelper.getWritableDatabase(), loader);
- editor.commit();
+ if ((mOpenHelper.loadFavorites(mOpenHelper.getWritableDatabase(), loader) <= 0)
+ && usingExternallyProvidedLayout) {
+ // Unable to load external layout. Cleanup and load the internal layout.
+ createEmptyDB();
+ mOpenHelper.loadFavorites(mOpenHelper.getWritableDatabase(),
+ getDefaultLayoutParser());
+ }
+ clearFlagEmptyDbCreated();
}
}
+ private DefaultLayoutParser getDefaultLayoutParser() {
+ int defaultLayout = LauncherAppState.getInstance()
+ .getDynamicGrid().getDeviceProfile().defaultLayoutId;
+ return new DefaultLayoutParser(getContext(), mOpenHelper.mAppWidgetHost,
+ mOpenHelper, getContext().getResources(), defaultLayout);
+ }
+
public void migrateLauncher2Shortcuts() {
mOpenHelper.migrateLauncher2Shortcuts(mOpenHelper.getWritableDatabase(),
Uri.parse(getContext().getString(R.string.old_launcher_provider_uri)));
}
- private static int getDefaultWorkspaceResourceId() {
- LauncherAppState app = LauncherAppState.getInstance();
- DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
- if (LauncherAppState.isDisableAllApps()) {
- return grid.defaultNoAllAppsLayoutId;
- } else {
- return grid.defaultLayoutId;
- }
- }
-
private static interface ContentValuesCallback {
public void onRow(ContentValues values);
}
@@ -392,38 +379,7 @@ public class LauncherProvider extends ContentProvider {
}
private static class DatabaseHelper extends SQLiteOpenHelper implements LayoutParserCallback {
- private static final String TAG_RESOLVE = "resolve";
- private static final String TAG_FAVORITES = "favorites";
- private static final String TAG_FAVORITE = "favorite";
- private static final String TAG_APPWIDGET = "appwidget";
- private static final String TAG_SHORTCUT = "shortcut";
- private static final String TAG_FOLDER = "folder";
- private static final String TAG_PARTNER_FOLDER = "partner-folder";
- private static final String TAG_EXTRA = "extra";
- private static final String TAG_INCLUDE = "include";
-
- // Style attrs -- "Favorite"
- private static final String ATTR_CLASS_NAME = "className";
- private static final String ATTR_PACKAGE_NAME = "packageName";
- private static final String ATTR_CONTAINER = "container";
- private static final String ATTR_SCREEN = "screen";
- private static final String ATTR_X = "x";
- private static final String ATTR_Y = "y";
- private static final String ATTR_SPAN_X = "spanX";
- private static final String ATTR_SPAN_Y = "spanY";
- private static final String ATTR_ICON = "icon";
- private static final String ATTR_TITLE = "title";
- private static final String ATTR_URI = "uri";
-
- // Style attrs -- "Include"
- private static final String ATTR_WORKSPACE = "workspace";
-
- // Style attrs -- "Extra"
- private static final String ATTR_KEY = "key";
- private static final String ATTR_VALUE = "value";
-
private final Context mContext;
- private final PackageManager mPackageManager;
private final AppWidgetHost mAppWidgetHost;
private long mMaxItemId = -1;
private long mMaxScreenId = -1;
@@ -431,9 +387,8 @@ public class LauncherProvider extends ContentProvider {
private boolean mNewDbCreated = false;
DatabaseHelper(Context context) {
- super(context, DATABASE_NAME, null, DATABASE_VERSION);
+ super(context, LauncherFiles.LAUNCHER_DB, null, DATABASE_VERSION);
mContext = context;
- mPackageManager = context.getPackageManager();
mAppWidgetHost = new AppWidgetHost(context, Launcher.APPWIDGET_HOST_ID);
// In the case where neither onCreate nor onUpgrade gets called, we read the maxId from
@@ -789,8 +744,8 @@ public class LauncherProvider extends ContentProvider {
}
// Add default hotseat icons
- loadFavorites(db, new SimpleWorkspaceLoader(this, mContext.getResources(),
- R.xml.update_workspace));
+ loadFavorites(db, new DefaultLayoutParser(mContext, mAppWidgetHost, this,
+ mContext.getResources(), R.xml.update_workspace));
version = 9;
}
@@ -1052,7 +1007,7 @@ public class LauncherProvider extends ContentProvider {
long id = c.getLong(idIndex);
byte[] data = c.getBlob(iconIndex);
try {
- Bitmap bitmap = Utilities.resampleIconBitmap(
+ Bitmap bitmap = Utilities.createIconBitmap(
BitmapFactory.decodeByteArray(data, 0, data.length),
mContext);
if (bitmap != null) {
@@ -1357,31 +1312,7 @@ public class LauncherProvider extends ContentProvider {
return rank;
}
- private static final void beginDocument(XmlPullParser parser, String firstElementName)
- throws XmlPullParserException, IOException {
- int type;
- while ((type = parser.next()) != XmlPullParser.START_TAG
- && type != XmlPullParser.END_DOCUMENT) {
- ;
- }
-
- if (type != XmlPullParser.START_TAG) {
- throw new XmlPullParserException("No start tag found");
- }
-
- if (!parser.getName().equals(firstElementName)) {
- throw new XmlPullParserException("Unexpected start tag: found " + parser.getName() +
- ", expected " + firstElementName);
- }
- }
-
- private static Intent buildMainIntent() {
- Intent intent = new Intent(Intent.ACTION_MAIN, null);
- intent.addCategory(Intent.CATEGORY_LAUNCHER);
- return intent;
- }
-
- private int loadFavorites(SQLiteDatabase db, WorkspaceLoader loader) {
+ private int loadFavorites(SQLiteDatabase db, AutoInstallsLayout loader) {
ArrayList<Long> screenIds = new ArrayList<Long>();
// TODO: Use multiple loaders with fall-back and transaction.
int count = loader.loadLayout(db, screenIds);
@@ -1408,547 +1339,9 @@ public class LauncherProvider extends ContentProvider {
return count;
}
- /**
- * Loads the default set of favorite packages from an xml file.
- *
- * @param db The database to write the values into
- * @param filterContainerId The specific container id of items to load
- * @param the set of screenIds which are used by the favorites
- */
- private int loadFavoritesRecursive(SQLiteDatabase db, Resources res, int workspaceResourceId,
- ArrayList<Long> screenIds) {
-
- ContentValues values = new ContentValues();
- if (LOGD) Log.v(TAG, String.format("Loading favorites from resid=0x%08x", workspaceResourceId));
-
- int count = 0;
- try {
- XmlResourceParser parser = res.getXml(workspaceResourceId);
- beginDocument(parser, TAG_FAVORITES);
-
- final int depth = parser.getDepth();
-
- int type;
- while (((type = parser.next()) != XmlPullParser.END_TAG ||
- parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) {
-
- if (type != XmlPullParser.START_TAG) {
- continue;
- }
-
- boolean added = false;
- final String name = parser.getName();
-
- if (TAG_INCLUDE.equals(name)) {
-
- final int resId = getAttributeResourceValue(parser, ATTR_WORKSPACE, 0);
-
- if (LOGD) Log.v(TAG, String.format(("%" + (2*(depth+1)) + "s<include workspace=%08x>"),
- "", resId));
-
- if (resId != 0 && resId != workspaceResourceId) {
- // recursively load some more favorites, why not?
- count += loadFavoritesRecursive(db, res, resId, screenIds);
- added = false;
- } else {
- Log.w(TAG, String.format("Skipping <include workspace=0x%08x>", resId));
- }
-
- if (LOGD) Log.v(TAG, String.format(("%" + (2*(depth+1)) + "s</include>"), ""));
- continue;
- }
-
- // Assuming it's a <favorite> at this point
- long container = LauncherSettings.Favorites.CONTAINER_DESKTOP;
- String strContainer = getAttributeValue(parser, ATTR_CONTAINER);
- if (strContainer != null) {
- container = Long.valueOf(strContainer);
- }
-
- String screen = getAttributeValue(parser, ATTR_SCREEN);
- String x = getAttributeValue(parser, ATTR_X);
- String y = getAttributeValue(parser, ATTR_Y);
-
- values.clear();
- values.put(LauncherSettings.Favorites.CONTAINER, container);
- values.put(LauncherSettings.Favorites.SCREEN, screen);
- values.put(LauncherSettings.Favorites.CELLX, x);
- values.put(LauncherSettings.Favorites.CELLY, y);
-
- if (LOGD) {
- final String title = getAttributeValue(parser, ATTR_TITLE);
- final String pkg = getAttributeValue(parser, ATTR_PACKAGE_NAME);
- final String something = title != null ? title : pkg;
- Log.v(TAG, String.format(
- ("%" + (2*(depth+1)) + "s<%s%s c=%d s=%s x=%s y=%s>"),
- "", name,
- (something == null ? "" : (" \"" + something + "\"")),
- container, screen, x, y));
- }
-
- if (TAG_FAVORITE.equals(name)) {
- long id = addAppShortcut(db, values, parser);
- added = id >= 0;
- } else if (TAG_APPWIDGET.equals(name)) {
- added = addAppWidget(parser, type, db, values);
- } else if (TAG_SHORTCUT.equals(name)) {
- long id = addUriShortcut(db, values, res, parser);
- added = id >= 0;
- } else if (TAG_RESOLVE.equals(name)) {
- // This looks through the contained favorites (or meta-favorites) and
- // attempts to add them as shortcuts in the fallback group's location
- // until one is added successfully.
- added = false;
- final int groupDepth = parser.getDepth();
- while ((type = parser.next()) != XmlPullParser.END_TAG ||
- parser.getDepth() > groupDepth) {
- if (type != XmlPullParser.START_TAG) {
- continue;
- }
- final String fallback_item_name = parser.getName();
- if (!added) {
- if (TAG_FAVORITE.equals(fallback_item_name)) {
- final long id = addAppShortcut(db, values, parser);
- added = id >= 0;
- } else {
- Log.e(TAG, "Fallback groups can contain only favorites, found "
- + fallback_item_name);
- }
- }
- }
- } else if (TAG_FOLDER.equals(name)) {
- // Folder contents are nested in this XML file
- added = loadFolder(db, values, res, parser);
-
- } else if (TAG_PARTNER_FOLDER.equals(name)) {
- // Folder contents come from an external XML resource
- final Partner partner = Partner.get(mPackageManager);
- if (partner != null) {
- final Resources partnerRes = partner.getResources();
- final int resId = partnerRes.getIdentifier(Partner.RES_FOLDER,
- "xml", partner.getPackageName());
- if (resId != 0) {
- final XmlResourceParser partnerParser = partnerRes.getXml(resId);
- beginDocument(partnerParser, TAG_FOLDER);
- added = loadFolder(db, values, partnerRes, partnerParser);
- }
- }
- }
- if (added) {
- long screenId = Long.parseLong(screen);
- // Keep track of the set of screens which need to be added to the db.
- if (!screenIds.contains(screenId) &&
- container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {
- screenIds.add(screenId);
- }
- count++;
- }
- }
- } catch (XmlPullParserException e) {
- Log.w(TAG, "Got exception parsing favorites.", e);
- } catch (IOException e) {
- Log.w(TAG, "Got exception parsing favorites.", e);
- } catch (RuntimeException e) {
- Log.w(TAG, "Got exception parsing favorites.", e);
- }
- return count;
- }
-
- /**
- * Parse folder items starting at {@link XmlPullParser} location. Allow recursive
- * includes of items.
- */
- private void addToFolder(SQLiteDatabase db, Resources res, XmlResourceParser parser,
- ArrayList<Long> folderItems, long folderId) throws IOException, XmlPullParserException {
- int type;
- int folderDepth = parser.getDepth();
- while ((type = parser.next()) != XmlPullParser.END_TAG ||
- parser.getDepth() > folderDepth) {
- if (type != XmlPullParser.START_TAG) {
- continue;
- }
- final String tag = parser.getName();
-
- final ContentValues childValues = new ContentValues();
- childValues.put(LauncherSettings.Favorites.CONTAINER, folderId);
-
- if (LOGD) {
- final String pkg = getAttributeValue(parser, ATTR_PACKAGE_NAME);
- final String uri = getAttributeValue(parser, ATTR_URI);
- Log.v(TAG, String.format(("%" + (2*(folderDepth+1)) + "s<%s \"%s\">"), "",
- tag, uri != null ? uri : pkg));
- }
-
- if (TAG_FAVORITE.equals(tag) && folderId >= 0) {
- final long id = addAppShortcut(db, childValues, parser);
- if (id >= 0) {
- folderItems.add(id);
- }
- } else if (TAG_SHORTCUT.equals(tag) && folderId >= 0) {
- final long id = addUriShortcut(db, childValues, res, parser);
- if (id >= 0) {
- folderItems.add(id);
- }
- } else if (TAG_INCLUDE.equals(tag) && folderId >= 0) {
- addToFolder(db, res, parser, folderItems, folderId);
- } else {
- throw new RuntimeException("Folders can contain only shortcuts");
- }
- }
- }
-
- /**
- * Parse folder starting at current {@link XmlPullParser} location.
- */
- private boolean loadFolder(SQLiteDatabase db, ContentValues values, Resources res,
- XmlResourceParser parser) throws IOException, XmlPullParserException {
- final String title;
- final int titleResId = getAttributeResourceValue(parser, ATTR_TITLE, 0);
- if (titleResId != 0) {
- title = res.getString(titleResId);
- } else {
- title = mContext.getResources().getString(R.string.folder_name);
- }
-
- values.put(LauncherSettings.Favorites.TITLE, title);
- long folderId = addFolder(db, values);
- boolean added = folderId >= 0;
-
- ArrayList<Long> folderItems = new ArrayList<Long>();
- addToFolder(db, res, parser, folderItems, folderId);
-
- // We can only have folders with >= 2 items, so we need to remove the
- // folder and clean up if less than 2 items were included, or some
- // failed to add, and less than 2 were actually added
- if (folderItems.size() < 2 && folderId >= 0) {
- // Delete the folder
- deleteId(db, folderId);
-
- // If we have a single item, promote it to where the folder
- // would have been.
- if (folderItems.size() == 1) {
- final ContentValues childValues = new ContentValues();
- copyInteger(values, childValues, LauncherSettings.Favorites.CONTAINER);
- copyInteger(values, childValues, LauncherSettings.Favorites.SCREEN);
- copyInteger(values, childValues, LauncherSettings.Favorites.CELLX);
- copyInteger(values, childValues, LauncherSettings.Favorites.CELLY);
-
- final long id = folderItems.get(0);
- db.update(TABLE_FAVORITES, childValues,
- LauncherSettings.Favorites._ID + "=" + id, null);
- } else {
- added = false;
- }
- }
- return added;
- }
-
- // A meta shortcut attempts to resolve an intent specified as a URI in the XML, if a
- // logical choice for what shortcut should be used for that intent exists, then it is
- // added. Otherwise add nothing.
- private long addAppShortcutByUri(SQLiteDatabase db, ContentValues values,
- String intentUri) {
- Intent metaIntent;
- try {
- metaIntent = Intent.parseUri(intentUri, 0);
- } catch (URISyntaxException e) {
- Log.e(TAG, "Unable to add meta-favorite: " + intentUri, e);
- return -1;
- }
-
- ResolveInfo resolved = mPackageManager.resolveActivity(metaIntent,
- PackageManager.MATCH_DEFAULT_ONLY);
- final List<ResolveInfo> appList = mPackageManager.queryIntentActivities(
- metaIntent, PackageManager.MATCH_DEFAULT_ONLY);
-
- // Verify that the result is an app and not just the resolver dialog asking which
- // app to use.
- if (wouldLaunchResolverActivity(resolved, appList)) {
- // If only one of the results is a system app then choose that as the default.
- final ResolveInfo systemApp = getSingleSystemActivity(appList);
- if (systemApp == null) {
- // There is no logical choice for this meta-favorite, so rather than making
- // a bad choice just add nothing.
- Log.w(TAG, "No preference or single system activity found for "
- + metaIntent.toString());
- return -1;
- }
- resolved = systemApp;
- }
- final ActivityInfo info = resolved.activityInfo;
- final Intent intent = mPackageManager.getLaunchIntentForPackage(info.packageName);
- if (intent == null) {
- return -1;
- }
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
- Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
-
- return addAppShortcut(db, values, info.loadLabel(mPackageManager).toString(), intent);
- }
-
- private ResolveInfo getSingleSystemActivity(List<ResolveInfo> appList) {
- ResolveInfo systemResolve = null;
- final int N = appList.size();
- for (int i = 0; i < N; ++i) {
- try {
- ApplicationInfo info = mPackageManager.getApplicationInfo(
- appList.get(i).activityInfo.packageName, 0);
- if ((info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
- if (systemResolve != null) {
- return null;
- } else {
- systemResolve = appList.get(i);
- }
- }
- } catch (PackageManager.NameNotFoundException e) {
- Log.w(TAG, "Unable to get info about resolve results", e);
- return null;
- }
- }
- return systemResolve;
- }
-
- private boolean wouldLaunchResolverActivity(ResolveInfo resolved,
- List<ResolveInfo> appList) {
- // If the list contains the above resolved activity, then it can't be
- // ResolverActivity itself.
- for (int i = 0; i < appList.size(); ++i) {
- ResolveInfo tmp = appList.get(i);
- if (tmp.activityInfo.name.equals(resolved.activityInfo.name)
- && tmp.activityInfo.packageName.equals(resolved.activityInfo.packageName)) {
- return false;
- }
- }
- return true;
- }
-
- private long addAppShortcut(SQLiteDatabase db, ContentValues values,
- XmlResourceParser parser) {
- final String packageName = getAttributeValue(parser, ATTR_PACKAGE_NAME);
- final String className = getAttributeValue(parser, ATTR_CLASS_NAME);
- final String uri = getAttributeValue(parser, ATTR_URI);
-
- if (!TextUtils.isEmpty(packageName) && !TextUtils.isEmpty(className)) {
- ActivityInfo info;
- try {
- ComponentName cn;
- try {
- cn = new ComponentName(packageName, className);
- info = mPackageManager.getActivityInfo(cn, 0);
- } catch (PackageManager.NameNotFoundException nnfe) {
- String[] packages = mPackageManager.currentToCanonicalPackageNames(
- new String[] { packageName });
- cn = new ComponentName(packages[0], className);
- info = mPackageManager.getActivityInfo(cn, 0);
- }
- final Intent intent = buildMainIntent();
- intent.setComponent(cn);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
- Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
-
- return addAppShortcut(db, values, info.loadLabel(mPackageManager).toString(),
- intent);
- } catch (PackageManager.NameNotFoundException e) {
- Log.w(TAG, "Unable to add favorite: " + packageName +
- "/" + className, e);
- }
- return -1;
- } else if (!TextUtils.isEmpty(uri)) {
- // If no component specified try to find a shortcut to add from the URI.
- return addAppShortcutByUri(db, values, uri);
- } else {
- Log.e(TAG, "Skipping invalid <favorite> with no component or uri");
- return -1;
- }
- }
-
- private long addAppShortcut(SQLiteDatabase db, ContentValues values, String title,
- Intent intent) {
- long id = generateNewItemId();
- values.put(Favorites.INTENT, intent.toUri(0));
- values.put(Favorites.TITLE, title);
- values.put(Favorites.ITEM_TYPE, Favorites.ITEM_TYPE_APPLICATION);
- values.put(Favorites.SPANX, 1);
- values.put(Favorites.SPANY, 1);
- values.put(Favorites._ID, id);
- if (dbInsertAndCheck(this, db, TABLE_FAVORITES, null, values) < 0) {
- return -1;
- } else {
- return id;
- }
- }
-
- private long addFolder(SQLiteDatabase db, ContentValues values) {
- values.put(Favorites.ITEM_TYPE, Favorites.ITEM_TYPE_FOLDER);
- values.put(Favorites.SPANX, 1);
- values.put(Favorites.SPANY, 1);
- long id = generateNewItemId();
- values.put(Favorites._ID, id);
- if (dbInsertAndCheck(this, db, TABLE_FAVORITES, null, values) <= 0) {
- return -1;
- } else {
- return id;
- }
- }
-
private ComponentName getSearchWidgetProvider() {
- SearchManager searchManager =
- (SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE);
- ComponentName searchComponent = searchManager.getGlobalSearchActivity();
- if (searchComponent == null) return null;
- return getProviderInPackage(searchComponent.getPackageName());
- }
-
- /**
- * Gets an appwidget provider from the given package. If the package contains more than
- * one appwidget provider, an arbitrary one is returned.
- */
- private ComponentName getProviderInPackage(String packageName) {
- AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(mContext);
- List<AppWidgetProviderInfo> providers = appWidgetManager.getInstalledProviders();
- if (providers == null) return null;
- final int providerCount = providers.size();
- for (int i = 0; i < providerCount; i++) {
- ComponentName provider = providers.get(i).provider;
- if (provider != null && provider.getPackageName().equals(packageName)) {
- return provider;
- }
- }
- return null;
- }
-
- private boolean addAppWidget(XmlResourceParser parser, int type,
- SQLiteDatabase db, ContentValues values)
- throws XmlPullParserException, IOException {
-
- String packageName = getAttributeValue(parser, ATTR_PACKAGE_NAME);
- String className = getAttributeValue(parser, ATTR_CLASS_NAME);
-
- if (packageName == null || className == null) {
- return false;
- }
-
- boolean hasPackage = true;
- ComponentName cn = new ComponentName(packageName, className);
- try {
- mPackageManager.getReceiverInfo(cn, 0);
- } catch (Exception e) {
- String[] packages = mPackageManager.currentToCanonicalPackageNames(
- new String[] { packageName });
- cn = new ComponentName(packages[0], className);
- try {
- mPackageManager.getReceiverInfo(cn, 0);
- } catch (Exception e1) {
- System.out.println("Can't find widget provider: " + className);
- hasPackage = false;
- }
- }
-
- if (hasPackage) {
- String spanX = getAttributeValue(parser, ATTR_SPAN_X);
- String spanY = getAttributeValue(parser, ATTR_SPAN_Y);
-
- values.put(Favorites.SPANX, spanX);
- values.put(Favorites.SPANY, spanY);
-
- // Read the extras
- Bundle extras = new Bundle();
- int widgetDepth = parser.getDepth();
- while ((type = parser.next()) != XmlPullParser.END_TAG ||
- parser.getDepth() > widgetDepth) {
- if (type != XmlPullParser.START_TAG) {
- continue;
- }
-
- if (TAG_EXTRA.equals(parser.getName())) {
- String key = getAttributeValue(parser, ATTR_KEY);
- String value = getAttributeValue(parser, ATTR_VALUE);
- if (key != null && value != null) {
- extras.putString(key, value);
- } else {
- throw new RuntimeException("Widget extras must have a key and value");
- }
- } else {
- throw new RuntimeException("Widgets can contain only extras");
- }
- }
-
- return addAppWidget(db, values, cn, extras);
- }
-
- return false;
- }
-
- private boolean addAppWidget(SQLiteDatabase db, ContentValues values, ComponentName cn,
- Bundle extras) {
- boolean allocatedAppWidgets = false;
- final AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(mContext);
-
- try {
- int appWidgetId = mAppWidgetHost.allocateAppWidgetId();
-
- values.put(Favorites.ITEM_TYPE, Favorites.ITEM_TYPE_APPWIDGET);
- values.put(Favorites.APPWIDGET_ID, appWidgetId);
- values.put(Favorites.APPWIDGET_PROVIDER, cn.flattenToString());
- values.put(Favorites._ID, generateNewItemId());
- dbInsertAndCheck(this, db, TABLE_FAVORITES, null, values);
-
- allocatedAppWidgets = true;
-
- // TODO: need to check return value
- appWidgetManager.bindAppWidgetIdIfAllowed(appWidgetId, cn);
-
- // Send a broadcast to configure the widget
- if (extras != null && !extras.isEmpty()) {
- Intent intent = new Intent(ACTION_APPWIDGET_DEFAULT_WORKSPACE_CONFIGURE);
- intent.setComponent(cn);
- intent.putExtras(extras);
- intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
- mContext.sendBroadcast(intent);
- }
- } catch (RuntimeException ex) {
- Log.e(TAG, "Problem allocating appWidgetId", ex);
- }
-
- return allocatedAppWidgets;
- }
-
- private long addUriShortcut(SQLiteDatabase db, ContentValues values, Resources res,
- XmlResourceParser parser) {
- final int iconResId = getAttributeResourceValue(parser, ATTR_ICON, 0);
- final int titleResId = getAttributeResourceValue(parser, ATTR_TITLE, 0);
-
- Intent intent;
- String uri = null;
- try {
- uri = getAttributeValue(parser, ATTR_URI);
- intent = Intent.parseUri(uri, 0);
- } catch (URISyntaxException e) {
- Log.w(TAG, "Shortcut has malformed uri: " + uri);
- return -1; // Oh well
- }
-
- if (iconResId == 0 || titleResId == 0) {
- Log.w(TAG, "Shortcut is missing title or icon resource ID");
- return -1;
- }
-
- long id = generateNewItemId();
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- values.put(Favorites.INTENT, intent.toUri(0));
- values.put(Favorites.TITLE, res.getString(titleResId));
- values.put(Favorites.ITEM_TYPE, Favorites.ITEM_TYPE_SHORTCUT);
- values.put(Favorites.SPANX, 1);
- values.put(Favorites.SPANY, 1);
- values.put(Favorites.ICON_TYPE, Favorites.ICON_TYPE_RESOURCE);
- values.put(Favorites.ICON_PACKAGE, res.getResourcePackageName(iconResId));
- values.put(Favorites.ICON_RESOURCE, res.getResourceName(iconResId));
- values.put(Favorites._ID, id);
-
- if (dbInsertAndCheck(this, db, TABLE_FAVORITES, null, values) < 0) {
- return -1;
- }
- return id;
+ AppWidgetProviderInfo searchProvider = Utilities.getSearchWidgetProvider(mContext);
+ return (searchProvider == null) ? null : searchProvider.provider;
}
private void migrateLauncher2Shortcuts(SQLiteDatabase db, Uri uri) {
@@ -2039,6 +1432,12 @@ public class LauncherProvider extends ContentProvider {
userHandle = UserHandleCompat.myUserHandle();
userSerialNumber = userManager.getSerialNumberForUser(userHandle);
}
+
+ if (userHandle == null) {
+ Launcher.addDumpLog(TAG, "skipping deleted user", true);
+ continue;
+ }
+
Launcher.addDumpLog(TAG, "migrating \""
+ c.getString(titleIndex) + "\" ("
+ cellX + "," + cellY + "@"
@@ -2077,9 +1476,13 @@ public class LauncherProvider extends ContentProvider {
// Canonicalize
// the Play Store sets the package parameter, but Launcher
- // does not, so we clear that out to keep them the same
+ // does not, so we clear that out to keep them the same.
+ // Also ignore intent flags for the purposes of deduping.
intent.setPackage(null);
+ int flags = intent.getFlags();
+ intent.setFlags(0);
final String key = intent.toUri(0);
+ intent.setFlags(flags);
if (seenIntents.contains(key)) {
Launcher.addDumpLog(TAG, "skipping duplicate", true);
continue;
@@ -2250,38 +1653,6 @@ public class LauncherProvider extends ContentProvider {
return selectWhere.toString();
}
- /**
- * Return attribute value, attempting launcher-specific namespace first
- * before falling back to anonymous attribute.
- */
- private static String getAttributeValue(XmlResourceParser parser, String attribute) {
- String value = parser.getAttributeValue(
- "http://schemas.android.com/apk/res-auto/com.android.launcher3", attribute);
- if (value == null) {
- value = parser.getAttributeValue(null, attribute);
- }
- return value;
- }
-
- /**
- * Return attribute resource value, attempting launcher-specific namespace
- * first before falling back to anonymous attribute.
- */
- private static int getAttributeResourceValue(XmlResourceParser parser, String attribute,
- int defaultValue) {
- int value = parser.getAttributeResourceValue(
- "http://schemas.android.com/apk/res-auto/com.android.launcher3", attribute,
- defaultValue);
- if (value == defaultValue) {
- value = parser.getAttributeResourceValue(null, attribute, defaultValue);
- }
- return value;
- }
-
- private static void copyInteger(ContentValues from, ContentValues to, String key) {
- to.put(key, from.getAsInteger(key));
- }
-
static class SqlArguments {
public final String table;
public final String where;
@@ -2313,29 +1684,4 @@ public class LauncherProvider extends ContentProvider {
}
}
}
-
- static interface WorkspaceLoader {
- /**
- * @param screenIds A mutable list of screen its
- * @return the number of workspace items added.
- */
- int loadLayout(SQLiteDatabase db, ArrayList<Long> screenIds);
- }
-
- private static class SimpleWorkspaceLoader implements WorkspaceLoader {
- private final Resources mRes;
- private final int mWorkspaceId;
- private final DatabaseHelper mHelper;
-
- SimpleWorkspaceLoader(DatabaseHelper helper, Resources res, int workspaceId) {
- mHelper = helper;
- mRes = res;
- mWorkspaceId = workspaceId;
- }
-
- @Override
- public int loadLayout(SQLiteDatabase db, ArrayList<Long> screenIds) {
- return mHelper.loadFavoritesRecursive(db, mRes, mWorkspaceId, screenIds);
- }
- }
}
diff --git a/src/com/android/launcher3/LauncherRootView.java b/src/com/android/launcher3/LauncherRootView.java
new file mode 100644
index 000000000..e8c11c48b
--- /dev/null
+++ b/src/com/android/launcher3/LauncherRootView.java
@@ -0,0 +1,17 @@
+package com.android.launcher3;
+
+import android.content.Context;
+import android.graphics.Rect;
+import android.util.AttributeSet;
+
+public class LauncherRootView extends InsettableFrameLayout {
+ public LauncherRootView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ @Override
+ protected boolean fitSystemWindows(Rect insets) {
+ setInsets(insets);
+ return true; // I'll take it from here
+ }
+} \ No newline at end of file
diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java
index 48fc0c98f..7d65f4686 100644
--- a/src/com/android/launcher3/PagedView.java
+++ b/src/com/android/launcher3/PagedView.java
@@ -204,6 +204,8 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
protected boolean mAllowLongPress = true;
+ private boolean mWasInOverscroll = false;
+
// Page Indicator
private int mPageIndicatorViewId;
private PageIndicator mPageIndicator;
@@ -625,6 +627,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
// a method that subclasses can override to add behavior
protected void onPageEndMoving() {
+ mWasInOverscroll = false;
}
/**
@@ -663,6 +666,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
if (isXBeforeFirstPage) {
super.scrollTo(0, y);
if (mAllowOverScroll) {
+ mWasInOverscroll = true;
if (isRtl) {
overScroll(x - mMaxScrollX);
} else {
@@ -672,6 +676,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
} else if (isXAfterLastPage) {
super.scrollTo(mMaxScrollX, y);
if (mAllowOverScroll) {
+ mWasInOverscroll = true;
if (isRtl) {
overScroll(x);
} else {
@@ -679,6 +684,10 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
}
}
} else {
+ if (mWasInOverscroll) {
+ overScroll(0);
+ mWasInOverscroll = false;
+ }
mOverScrollX = x;
super.scrollTo(x, y);
}
@@ -1513,6 +1522,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
mLastMotionXRemainder = 0;
mTouchX = getViewportOffsetX() + getScrollX();
mSmoothingTime = System.nanoTime() / NANOTIME_DIV;
+ onScrollInteractionBegin();
pageBeginMoving();
}
}
@@ -1752,6 +1762,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
mActivePointerId = ev.getPointerId(0);
if (mTouchState == TOUCH_STATE_SCROLLING) {
+ onScrollInteractionBegin();
pageBeginMoving();
}
break;
@@ -1940,6 +1951,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
getScrollY(), vX, 0, Integer.MIN_VALUE, Integer.MAX_VALUE, 0, 0);
invalidate();
}
+ onScrollInteractionEnd();
} else if (mTouchState == TOUCH_STATE_PREV_PAGE) {
// at this point we have not moved beyond the touch slop
// (otherwise mTouchState would be TOUCH_STATE_SCROLLING), so
@@ -2025,6 +2037,15 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
mActivePointerId = INVALID_POINTER;
}
+ /**
+ * Triggered by scrolling via touch
+ */
+ protected void onScrollInteractionBegin() {
+ }
+
+ protected void onScrollInteractionEnd() {
+ }
+
protected void onUnhandledTap(MotionEvent ev) {
((Launcher) getContext()).onClick(this);
}
diff --git a/src/com/android/launcher3/PagedViewWidgetImageView.java b/src/com/android/launcher3/PagedViewWidgetImageView.java
index 71f5eead3..7d8279547 100644
--- a/src/com/android/launcher3/PagedViewWidgetImageView.java
+++ b/src/com/android/launcher3/PagedViewWidgetImageView.java
@@ -21,7 +21,7 @@ import android.graphics.Canvas;
import android.util.AttributeSet;
import android.widget.ImageView;
-class PagedViewWidgetImageView extends ImageView {
+public class PagedViewWidgetImageView extends ImageView {
public boolean mAllowRequestLayout = true;
public PagedViewWidgetImageView(Context context, AttributeSet attrs) {
diff --git a/src/com/android/launcher3/PagedViewWithDraggableItems.java b/src/com/android/launcher3/PagedViewWithDraggableItems.java
index 2a29c33f3..0e593698d 100644
--- a/src/com/android/launcher3/PagedViewWithDraggableItems.java
+++ b/src/com/android/launcher3/PagedViewWithDraggableItems.java
@@ -91,6 +91,10 @@ public abstract class PagedViewWithDraggableItems extends PagedView
return super.onTouchEvent(ev);
}
+ public void trimMemory() {
+ mLastTouchedItem = null;
+ }
+
@Override
public boolean onTouch(View v, MotionEvent event) {
mLastTouchedItem = v;
diff --git a/src/com/android/launcher3/PendingAppWidgetHostView.java b/src/com/android/launcher3/PendingAppWidgetHostView.java
index d23a33033..179c60a98 100644
--- a/src/com/android/launcher3/PendingAppWidgetHostView.java
+++ b/src/com/android/launcher3/PendingAppWidgetHostView.java
@@ -41,9 +41,9 @@ public class PendingAppWidgetHostView extends LauncherAppWidgetHostView implemen
private final LauncherAppWidgetInfo mInfo;
private final int mStartState;
private final Intent mIconLookupIntent;
+ private final boolean mDisabledForSafeMode;
private Bitmap mIcon;
- private PreloadIconDrawable mDrawable;
private Drawable mCenterDrawable;
private Drawable mTopCornerDrawable;
@@ -53,11 +53,13 @@ public class PendingAppWidgetHostView extends LauncherAppWidgetHostView implemen
private final TextPaint mPaint;
private Layout mSetupTextLayout;
- public PendingAppWidgetHostView(Context context, LauncherAppWidgetInfo info) {
+ public PendingAppWidgetHostView(Context context, LauncherAppWidgetInfo info,
+ boolean disabledForSafeMode) {
super(context);
mInfo = info;
mStartState = info.restoreStatus;
mIconLookupIntent = new Intent().setComponent(info.providerName);
+ mDisabledForSafeMode = disabledForSafeMode;
mPaint = new TextPaint();
mPaint.setColor(0xFFFFFFFF);
@@ -106,14 +108,21 @@ public class PendingAppWidgetHostView extends LauncherAppWidgetHostView implemen
return;
}
mIcon = icon;
- if (mDrawable != null) {
- mDrawable.setCallback(null);
- mDrawable = null;
+ if (mCenterDrawable != null) {
+ mCenterDrawable.setCallback(null);
+ mCenterDrawable = null;
}
if (mIcon != null) {
- // The view displays two modes, one with a setup icon and another with a preload icon
- // in the center.
- if (isReadyForClickSetup()) {
+ // The view displays three modes,
+ // 1) App icon in the center
+ // 2) Preload icon in the center
+ // 3) Setup icon in the center and app icon in the top right corner.
+ if (mDisabledForSafeMode) {
+ FastBitmapDrawable disabledIcon = Utilities.createIconDrawable(mIcon);
+ disabledIcon.setGhostModeEnabled(true);
+ mCenterDrawable = disabledIcon;
+ mTopCornerDrawable = null;
+ } else if (isReadyForClickSetup()) {
mCenterDrawable = getResources().getDrawable(R.drawable.ic_setting);
mTopCornerDrawable = new FastBitmapDrawable(mIcon);
} else {
@@ -123,8 +132,9 @@ public class PendingAppWidgetHostView extends LauncherAppWidgetHostView implemen
}
FastBitmapDrawable drawable = Utilities.createIconDrawable(mIcon);
- mDrawable = new PreloadIconDrawable(drawable, sPreloaderTheme);
- mDrawable.setCallback(this);
+ mCenterDrawable = new PreloadIconDrawable(drawable, sPreloaderTheme);
+ mCenterDrawable.setCallback(this);
+ mTopCornerDrawable = null;
applyState();
}
mDrawableSizeChanged = true;
@@ -133,12 +143,12 @@ public class PendingAppWidgetHostView extends LauncherAppWidgetHostView implemen
@Override
protected boolean verifyDrawable(Drawable who) {
- return (who == mDrawable) || super.verifyDrawable(who);
+ return (who == mCenterDrawable) || super.verifyDrawable(who);
}
public void applyState() {
- if (mDrawable != null) {
- mDrawable.setLevel(Math.max(mInfo.installProgress, 0));
+ if (mCenterDrawable != null) {
+ mCenterDrawable.setLevel(Math.max(mInfo.installProgress, 0));
}
}
@@ -158,23 +168,30 @@ public class PendingAppWidgetHostView extends LauncherAppWidgetHostView implemen
@Override
protected void onDraw(Canvas canvas) {
- if (mDrawable != null) {
+ if (mCenterDrawable == null) {
+ // Nothing to draw
+ return;
+ }
+
+ if (mTopCornerDrawable == null) {
if (mDrawableSizeChanged) {
+ int outset = (mCenterDrawable instanceof PreloadIconDrawable) ?
+ ((PreloadIconDrawable) mCenterDrawable).getOutset() : 0;
int maxSize = LauncherAppState.getInstance().getDynamicGrid()
- .getDeviceProfile().iconSizePx + 2 * mDrawable.getOutset();
+ .getDeviceProfile().iconSizePx + 2 * outset;
int size = Math.min(maxSize, Math.min(
getWidth() - getPaddingLeft() - getPaddingRight(),
getHeight() - getPaddingTop() - getPaddingBottom()));
mRect.set(0, 0, size, size);
- mRect.inset(mDrawable.getOutset(), mDrawable.getOutset());
+ mRect.inset(outset, outset);
mRect.offsetTo((getWidth() - mRect.width()) / 2, (getHeight() - mRect.height()) / 2);
- mDrawable.setBounds(mRect);
+ mCenterDrawable.setBounds(mRect);
mDrawableSizeChanged = false;
}
-
- mDrawable.draw(canvas);
- } else if ((mCenterDrawable != null) && (mTopCornerDrawable != null)) {
+ mCenterDrawable.draw(canvas);
+ } else {
+ // Draw the top corner icon and "Setup" text is possible
if (mDrawableSizeChanged) {
DeviceProfile grid = getDeviceProfile();
int iconSize = grid.iconSizePx;
diff --git a/src/com/android/launcher3/SearchDropTargetBar.java b/src/com/android/launcher3/SearchDropTargetBar.java
index 435dbda1d..99c2e0859 100644
--- a/src/com/android/launcher3/SearchDropTargetBar.java
+++ b/src/com/android/launcher3/SearchDropTargetBar.java
@@ -19,9 +19,9 @@ package com.android.launcher3;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
+import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.AccelerateInterpolator;
@@ -37,7 +37,7 @@ public class SearchDropTargetBar extends FrameLayout implements DragController.D
private static final int sTransitionOutDuration = 175;
private ObjectAnimator mDropTargetBarAnim;
- private ObjectAnimator mQSBSearchBarAnim;
+ private ValueAnimator mQSBSearchBarAnim;
private static final AccelerateInterpolator sAccelerateInterpolator =
new AccelerateInterpolator();
@@ -49,7 +49,6 @@ public class SearchDropTargetBar extends FrameLayout implements DragController.D
private int mBarHeight;
private boolean mDeferOnDragEnd = false;
- private Drawable mPreviousBackground;
private boolean mEnableDropDownDropTargets;
public SearchDropTargetBar(Context context, AttributeSet attrs) {
@@ -69,29 +68,42 @@ public class SearchDropTargetBar extends FrameLayout implements DragController.D
dragController.setFlingToDeleteDropTarget(mDeleteDropTarget);
mInfoDropTarget.setLauncher(launcher);
mDeleteDropTarget.setLauncher(launcher);
- mQSBSearchBar = launcher.getQsbBar();
- if (mEnableDropDownDropTargets) {
- mQSBSearchBarAnim = LauncherAnimUtils.ofFloat(mQSBSearchBar, "translationY", 0,
- -mBarHeight);
+ }
+
+ public void setQsbSearchBar(View qsb) {
+ mQSBSearchBar = qsb;
+ if (mQSBSearchBar != null) {
+ if (mEnableDropDownDropTargets) {
+ mQSBSearchBarAnim = LauncherAnimUtils.ofFloat(mQSBSearchBar, "translationY", 0,
+ -mBarHeight);
+ } else {
+ mQSBSearchBarAnim = LauncherAnimUtils.ofFloat(mQSBSearchBar, "alpha", 1f, 0f);
+ }
+ setupAnimation(mQSBSearchBarAnim, mQSBSearchBar);
} else {
- mQSBSearchBarAnim = LauncherAnimUtils.ofFloat(mQSBSearchBar, "alpha", 1f, 0f);
+ // Create a no-op animation of the search bar is null
+ mQSBSearchBarAnim = ValueAnimator.ofFloat(0, 0);
+ mQSBSearchBarAnim.setDuration(sTransitionInDuration);
}
- setupAnimation(mQSBSearchBarAnim, mQSBSearchBar);
}
private void prepareStartAnimation(View v) {
// Enable the hw layers before the animation starts (will be disabled in the onAnimationEnd
// callback below)
- v.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+ if (v != null) {
+ v.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+ }
}
- private void setupAnimation(ObjectAnimator anim, final View v) {
+ private void setupAnimation(ValueAnimator anim, final View v) {
anim.setInterpolator(sAccelerateInterpolator);
anim.setDuration(sTransitionInDuration);
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
- v.setLayerType(View.LAYER_TYPE_NONE, null);
+ if (v != null) {
+ v.setLayerType(View.LAYER_TYPE_NONE, null);
+ }
}
});
}
@@ -145,9 +157,9 @@ public class SearchDropTargetBar extends FrameLayout implements DragController.D
mQSBSearchBarAnim.reverse();
} else {
mQSBSearchBarAnim.cancel();
- if (mEnableDropDownDropTargets) {
+ if (mQSBSearchBar != null && mEnableDropDownDropTargets) {
mQSBSearchBar.setTranslationY(0);
- } else {
+ } else if (mQSBSearchBar != null) {
mQSBSearchBar.setAlpha(1f);
}
}
@@ -161,9 +173,9 @@ public class SearchDropTargetBar extends FrameLayout implements DragController.D
mQSBSearchBarAnim.start();
} else {
mQSBSearchBarAnim.cancel();
- if (mEnableDropDownDropTargets) {
+ if (mQSBSearchBar != null && mEnableDropDownDropTargets) {
mQSBSearchBar.setTranslationY(-mBarHeight);
- } else {
+ } else if (mQSBSearchBar != null) {
mQSBSearchBar.setAlpha(0f);
}
}
@@ -213,20 +225,6 @@ public class SearchDropTargetBar extends FrameLayout implements DragController.D
}
}
- public void onSearchPackagesChanged(boolean searchVisible, boolean voiceVisible) {
- if (mQSBSearchBar != null) {
- Drawable bg = mQSBSearchBar.getBackground();
- if (bg != null && (!searchVisible && !voiceVisible)) {
- // Save the background and disable it
- mPreviousBackground = bg;
- mQSBSearchBar.setBackgroundResource(0);
- } else if (mPreviousBackground != null && (searchVisible || voiceVisible)) {
- // Restore the background
- mQSBSearchBar.setBackground(mPreviousBackground);
- }
- }
- }
-
public Rect getSearchBarBounds() {
if (mQSBSearchBar != null) {
final int[] pos = new int[2];
diff --git a/src/com/android/launcher3/ShortcutInfo.java b/src/com/android/launcher3/ShortcutInfo.java
index daf343460..01f79314e 100644
--- a/src/com/android/launcher3/ShortcutInfo.java
+++ b/src/com/android/launcher3/ShortcutInfo.java
@@ -88,10 +88,20 @@ public class ShortcutInfo extends ItemInfo {
private Bitmap mIcon;
/**
+ * Indicates that the icon is disabled due to safe mode restrictions.
+ */
+ public static final int FLAG_DISABLED_SAFEMODE = 1;
+
+ /**
+ * Indicates that the icon is disabled as the app is not available.
+ */
+ public static final int FLAG_DISABLED_NOT_AVAILABLE = 2;
+
+ /**
* Could be disabled, if the the app is installed but unavailable (eg. in safe mode or when
* sd-card is not available).
*/
- boolean isDisabled = false;
+ int isDisabled = DEFAULT;
int status;
diff --git a/src/com/android/launcher3/Stats.java b/src/com/android/launcher3/Stats.java
index f3977e456..a87986562 100644
--- a/src/com/android/launcher3/Stats.java
+++ b/src/com/android/launcher3/Stats.java
@@ -38,12 +38,10 @@ public class Stats {
public static final String EXTRA_CELLX = "cellX";
public static final String EXTRA_CELLY = "cellY";
- private static final String LOG_FILE_NAME = "launches.log";
private static final int LOG_VERSION = 1;
private static final int LOG_TAG_VERSION = 0x1;
private static final int LOG_TAG_LAUNCH = 0x1000;
- private static final String STATS_FILE_NAME = "stats.log";
private static final int STATS_VERSION = 1;
private static final int INITIAL_STATS_SIZE = 100;
@@ -69,7 +67,8 @@ public class Stats {
if (LOCAL_LAUNCH_LOG) {
try {
- mLog = new DataOutputStream(mLauncher.openFileOutput(LOG_FILE_NAME, Context.MODE_APPEND));
+ mLog = new DataOutputStream(mLauncher.openFileOutput(
+ LauncherFiles.LAUNCHES_LOG, Context.MODE_APPEND));
mLog.writeInt(LOG_TAG_VERSION);
mLog.writeInt(LOG_VERSION);
} catch (FileNotFoundException e) {
@@ -160,7 +159,8 @@ public class Stats {
private void saveStats() {
DataOutputStream stats = null;
try {
- stats = new DataOutputStream(mLauncher.openFileOutput(STATS_FILE_NAME + ".tmp", Context.MODE_PRIVATE));
+ stats = new DataOutputStream(mLauncher.openFileOutput(
+ LauncherFiles.STATS_LOG + ".tmp", Context.MODE_PRIVATE));
stats.writeInt(STATS_VERSION);
final int N = mHistogram.size();
stats.writeInt(N);
@@ -170,8 +170,8 @@ public class Stats {
}
stats.close();
stats = null;
- mLauncher.getFileStreamPath(STATS_FILE_NAME + ".tmp")
- .renameTo(mLauncher.getFileStreamPath(STATS_FILE_NAME));
+ mLauncher.getFileStreamPath(LauncherFiles.STATS_LOG + ".tmp")
+ .renameTo(mLauncher.getFileStreamPath(LauncherFiles.STATS_LOG));
} catch (FileNotFoundException e) {
Log.e(TAG, "unable to create stats data: " + e);
} catch (IOException e) {
@@ -190,7 +190,7 @@ public class Stats {
mHistogram = new ArrayList<Integer>(INITIAL_STATS_SIZE);
DataInputStream stats = null;
try {
- stats = new DataInputStream(mLauncher.openFileInput(STATS_FILE_NAME));
+ stats = new DataInputStream(mLauncher.openFileInput(LauncherFiles.STATS_LOG));
final int version = stats.readInt();
if (version == STATS_VERSION) {
final int N = stats.readInt();
diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java
index 80d4b22ce..215d63d2e 100644
--- a/src/com/android/launcher3/Utilities.java
+++ b/src/com/android/launcher3/Utilities.java
@@ -16,7 +16,11 @@
package com.android.launcher3;
+import android.annotation.TargetApi;
import android.app.Activity;
+import android.app.SearchManager;
+import android.appwidget.AppWidgetManager;
+import android.appwidget.AppWidgetProviderInfo;
import android.content.ActivityNotFoundException;
import android.content.ComponentName;
import android.content.Context;
@@ -54,8 +58,6 @@ public final class Utilities {
private static int sIconWidth = -1;
private static int sIconHeight = -1;
- public static int sIconTextureWidth = -1;
- public static int sIconTextureHeight = -1;
private static final Rect sOldBounds = new Rect();
private static final Canvas sCanvas = new Canvas();
@@ -89,10 +91,10 @@ public final class Utilities {
* Resizes an icon drawable to the correct icon size.
*/
static void resizeIconDrawable(Drawable icon) {
- icon.setBounds(0, 0, sIconTextureWidth, sIconTextureHeight);
+ icon.setBounds(0, 0, sIconWidth, sIconHeight);
}
- private static boolean isPropertyEnabled(String propertyName) {
+ public static boolean isPropertyEnabled(String propertyName) {
return Log.isLoggable(propertyName, Log.VERBOSE);
}
@@ -106,33 +108,43 @@ public final class Utilities {
* Indicates if the device is running LMP or higher.
*/
public static boolean isLmpOrAbove() {
- return Build.VERSION.SDK_INT >= Build.VERSION_CODES.L;
+ return Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP;
}
/**
- * Returns a bitmap suitable for the all apps view. Used to convert pre-ICS
- * icon bitmaps that are stored in the database (which were 74x74 pixels at hdpi size)
- * to the proper size (48dp)
+ * Returns a bitmap suitable for the all apps view. If the package or the resource do not
+ * exist, it returns null.
+ */
+ static Bitmap createIconBitmap(String packageName, String resourceName, IconCache cache,
+ Context context) {
+ PackageManager packageManager = context.getPackageManager();
+ // the resource
+ try {
+ Resources resources = packageManager.getResourcesForApplication(packageName);
+ if (resources != null) {
+ final int id = resources.getIdentifier(resourceName, null, null);
+ return createIconBitmap(
+ resources.getDrawableForDensity(id, cache.getFullResIconDpi()), context);
+ }
+ } catch (Exception e) {
+ // Icon not found.
+ }
+ return null;
+ }
+
+ /**
+ * Returns a bitmap which is of the appropriate size to be displayed as an icon
*/
static Bitmap createIconBitmap(Bitmap icon, Context context) {
- int textureWidth = sIconTextureWidth;
- int textureHeight = sIconTextureHeight;
- int sourceWidth = icon.getWidth();
- int sourceHeight = icon.getHeight();
- if (sourceWidth > textureWidth && sourceHeight > textureHeight) {
- // Icon is bigger than it should be; clip it (solves the GB->ICS migration case)
- return Bitmap.createBitmap(icon,
- (sourceWidth - textureWidth) / 2,
- (sourceHeight - textureHeight) / 2,
- textureWidth, textureHeight);
- } else if (sourceWidth == textureWidth && sourceHeight == textureHeight) {
- // Icon is the right size, no need to change it
+ synchronized (sCanvas) { // we share the statics :-(
+ if (sIconWidth == -1) {
+ initStatics(context);
+ }
+ }
+ if (sIconWidth == icon.getWidth() && sIconHeight == icon.getHeight()) {
return icon;
- } else {
- // Icon is too small, render to a larger bitmap
- final Resources resources = context.getResources();
- return createIconBitmap(new BitmapDrawable(resources, icon), context);
}
+ return createIconBitmap(new BitmapDrawable(context.getResources(), icon), context);
}
/**
@@ -172,8 +184,8 @@ public final class Utilities {
}
// no intrinsic size --> use default size
- int textureWidth = sIconTextureWidth;
- int textureHeight = sIconTextureHeight;
+ int textureWidth = sIconWidth;
+ int textureHeight = sIconHeight;
final Bitmap bitmap = Bitmap.createBitmap(textureWidth, textureHeight,
Bitmap.Config.ARGB_8888);
@@ -205,30 +217,6 @@ public final class Utilities {
}
/**
- * Returns a Bitmap representing the thumbnail of the specified Bitmap.
- *
- * @param bitmap The bitmap to get a thumbnail of.
- * @param context The application's context.
- *
- * @return A thumbnail for the specified bitmap or the bitmap itself if the
- * thumbnail could not be created.
- */
- static Bitmap resampleIconBitmap(Bitmap bitmap, Context context) {
- synchronized (sCanvas) { // we share the statics :-(
- if (sIconWidth == -1) {
- initStatics(context);
- }
-
- if (bitmap.getWidth() == sIconWidth && bitmap.getHeight() == sIconHeight) {
- return bitmap;
- } else {
- final Resources resources = context.getResources();
- return createIconBitmap(new BitmapDrawable(resources, bitmap), context);
- }
- }
- }
-
- /**
* Given a coordinate relative to the descendant, find the coordinate in a parent view's
* coordinates.
*
@@ -330,12 +318,10 @@ public final class Utilities {
private static void initStatics(Context context) {
final Resources resources = context.getResources();
sIconWidth = sIconHeight = (int) resources.getDimension(R.dimen.app_icon_size);
- sIconTextureWidth = sIconTextureHeight = sIconWidth;
}
public static void setIconSize(int widthPx) {
sIconWidth = sIconHeight = widthPx;
- sIconTextureWidth = sIconTextureHeight = widthPx;
}
public static void scaleRect(Rect r, float scale) {
@@ -513,4 +499,47 @@ public final class Utilities {
}
return null;
}
+
+ @TargetApi(Build.VERSION_CODES.KITKAT)
+ public static boolean isViewAttachedToWindow(View v) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
+ return v.isAttachedToWindow();
+ } else {
+ // A proxy call which returns null, if the view is not attached to the window.
+ return v.getKeyDispatcherState() != null;
+ }
+ }
+
+ /**
+ * Returns a widget with category {@link AppWidgetProviderInfo#WIDGET_CATEGORY_SEARCHBOX}
+ * provided by the same package which is set to be global search activity.
+ * If widgetCategory is not supported, or no such widget is found, returns the first widget
+ * provided by the package.
+ */
+ @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
+ public static AppWidgetProviderInfo getSearchWidgetProvider(Context context) {
+ SearchManager searchManager =
+ (SearchManager) context.getSystemService(Context.SEARCH_SERVICE);
+ ComponentName searchComponent = searchManager.getGlobalSearchActivity();
+ if (searchComponent == null) return null;
+ String providerPkg = searchComponent.getPackageName();
+
+ AppWidgetProviderInfo defaultWidgetForSearchPackage = null;
+
+ AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
+ for (AppWidgetProviderInfo info : appWidgetManager.getInstalledProviders()) {
+ if (info.provider.getPackageName().equals(providerPkg)) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
+ if ((info.widgetCategory & AppWidgetProviderInfo.WIDGET_CATEGORY_SEARCHBOX) != 0) {
+ return info;
+ } else if (defaultWidgetForSearchPackage == null) {
+ defaultWidgetForSearchPackage = info;
+ }
+ } else {
+ return info;
+ }
+ }
+ }
+ return defaultWidgetForSearchPackage;
+ }
}
diff --git a/src/com/android/launcher3/WidgetPreviewLoader.java b/src/com/android/launcher3/WidgetPreviewLoader.java
index 5aa719027..4e6fe1f88 100644
--- a/src/com/android/launcher3/WidgetPreviewLoader.java
+++ b/src/com/android/launcher3/WidgetPreviewLoader.java
@@ -12,6 +12,7 @@ import android.database.sqlite.SQLiteCantOpenDatabaseException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDiskIOException;
import android.database.sqlite.SQLiteOpenHelper;
+import android.database.sqlite.SQLiteReadOnlyDatabaseException;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
@@ -26,8 +27,8 @@ import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
+import android.os.Build;
import android.util.Log;
-
import com.android.launcher3.compat.AppWidgetManagerCompat;
import java.io.ByteArrayOutputStream;
@@ -130,8 +131,8 @@ public class WidgetPreviewLoader {
private final PaintCache mDefaultAppWidgetPreviewPaint = new PaintCache();
private final BitmapFactoryOptionsCache mCachedBitmapFactoryOptions = new BitmapFactoryOptionsCache();
- private final HashMap<String, WeakReference<Bitmap>> mLoadedPreviews = new HashMap<>();
- private final ArrayList<SoftReference<Bitmap>> mUnusedBitmaps = new ArrayList<>();
+ private final HashMap<String, WeakReference<Bitmap>> mLoadedPreviews = new HashMap<String, WeakReference<Bitmap>>();
+ private final ArrayList<SoftReference<Bitmap>> mUnusedBitmaps = new ArrayList<SoftReference<Bitmap>>();
private final Context mContext;
private final int mAppIconSize;
@@ -165,14 +166,24 @@ public class WidgetPreviewLoader {
LauncherAppState.getSharedPreferencesKey(), Context.MODE_PRIVATE);
final String lastVersionName = sp.getString(ANDROID_INCREMENTAL_VERSION_NAME_KEY, null);
final String versionName = android.os.Build.VERSION.INCREMENTAL;
+ final boolean isLollipopOrGreater = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP;
if (!versionName.equals(lastVersionName)) {
- // clear all the previews whenever the system version changes, to ensure that previews
- // are up-to-date for any apps that might have been updated with the system
- clearDb();
-
- SharedPreferences.Editor editor = sp.edit();
- editor.putString(ANDROID_INCREMENTAL_VERSION_NAME_KEY, versionName);
- editor.commit();
+ try {
+ // clear all the previews whenever the system version changes, to ensure that
+ // previews are up-to-date for any apps that might have been updated with the system
+ clearDb();
+ } catch (SQLiteReadOnlyDatabaseException e) {
+ if (isLollipopOrGreater) {
+ // Workaround for Bug. 18554839, if we fail to clear the db due to the read-only
+ // issue, then ignore this error and leave the old previews
+ } else {
+ throw e;
+ }
+ } finally {
+ SharedPreferences.Editor editor = sp.edit();
+ editor.putString(ANDROID_INCREMENTAL_VERSION_NAME_KEY, versionName);
+ editor.commit();
+ }
}
}
@@ -287,7 +298,6 @@ public class WidgetPreviewLoader {
static class CacheDb extends SQLiteOpenHelper {
final static int DB_VERSION = 2;
- final static String DB_NAME = "widgetpreviews.db";
final static String TABLE_NAME = "shortcut_and_widget_previews";
final static String COLUMN_NAME = "name";
final static String COLUMN_SIZE = "size";
@@ -295,7 +305,8 @@ public class WidgetPreviewLoader {
Context mContext;
public CacheDb(Context context) {
- super(context, new File(context.getCacheDir(), DB_NAME).getPath(), null, DB_VERSION);
+ super(context, new File(context.getCacheDir(),
+ LauncherFiles.WIDGET_PREVIEWS_DB).getPath(), null, DB_VERSION);
// Store the context for later use
mContext = context;
}
@@ -638,7 +649,7 @@ public class WidgetPreviewLoader {
c.setBitmap(null);
}
// Render the icon
- Drawable icon = mutateOnMainThread(mIconCache.getFullResIcon(info));
+ Drawable icon = mutateOnMainThread(mIconCache.getFullResIcon(info.activityInfo));
int paddingTop = mContext.
getResources().getDimensionPixelOffset(R.dimen.shortcut_preview_padding_top);
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 774996e56..8bd799198 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -67,6 +67,7 @@ import android.widget.TextView;
import com.android.launcher3.FolderIcon.FolderRingAnimator;
import com.android.launcher3.Launcher.CustomContentCallbacks;
+import com.android.launcher3.Launcher.LauncherOverlay;
import com.android.launcher3.LauncherSettings.Favorites;
import com.android.launcher3.compat.PackageInstallerCompat;
import com.android.launcher3.compat.PackageInstallerCompat.PackageInstallInfo;
@@ -282,6 +283,7 @@ public class Workspace extends SmoothPagedView
private float[] mNewAlphas;
private int mLastChildCount = -1;
private float mTransitionProgress;
+ private Animator mStateAnimator = null;
float mOverScrollEffect = 0f;
@@ -289,6 +291,13 @@ public class Workspace extends SmoothPagedView
private boolean mDeferDropAfterUninstall;
private boolean mUninstallSuccessful;
+ // State related to Launcher Overlay
+ LauncherOverlay mLauncherOverlay;
+ boolean mScrollInteractionBegan;
+ boolean mStartedSendingScrollEvents;
+ boolean mShouldSendPageSettled;
+ int mLastOverlaySroll = 0;
+
private final Runnable mBindPages = new Runnable() {
@Override
public void run() {
@@ -1249,6 +1258,66 @@ public class Workspace extends SmoothPagedView
stripEmptyScreens();
mStripScreensOnPageStopMoving = false;
}
+
+ if (mShouldSendPageSettled) {
+ mLauncherOverlay.onScrollSettled();
+ mShouldSendPageSettled = false;
+ }
+ }
+
+ protected void onScrollInteractionBegin() {
+ super.onScrollInteractionEnd();
+ mScrollInteractionBegan = true;
+ }
+
+ protected void onScrollInteractionEnd() {
+ super.onScrollInteractionEnd();
+ mScrollInteractionBegan = false;
+ if (mStartedSendingScrollEvents) {
+ mStartedSendingScrollEvents = false;
+ mLauncherOverlay.onScrollInteractionEnd();
+ }
+ }
+
+ public void setLauncherOverlay(LauncherOverlay overlay) {
+ mLauncherOverlay = overlay;
+ }
+
+ @Override
+ protected void overScroll(float amount) {
+ boolean isRtl = isLayoutRtl();
+ boolean shouldOverScroll = (amount <= 0 && (!hasCustomContent() || isRtl)) ||
+ (amount >= 0 && (!hasCustomContent() || !isRtl));
+
+ boolean shouldScrollOverlay = mLauncherOverlay != null &&
+ ((amount <= 0 && !isRtl) || (amount >= 0 && isRtl));
+
+ boolean shouldZeroOverlay = mLauncherOverlay != null && mLastOverlaySroll != 0 &&
+ ((amount >= 0 && !isRtl) || (amount <= 0 && isRtl));
+
+ if (shouldScrollOverlay) {
+ if (!mStartedSendingScrollEvents && mScrollInteractionBegan) {
+ mStartedSendingScrollEvents = true;
+ mLauncherOverlay.onScrollInteractionBegin();
+ mShouldSendPageSettled = true;
+ }
+ int screenSize = getViewportWidth();
+ float f = (amount / screenSize);
+
+ int progress = (int) Math.abs((f * 100));
+
+ mLastOverlaySroll = progress;
+ mLauncherOverlay.onScrollChange(progress, isRtl);
+ } else if (shouldOverScroll) {
+ dampedOverScroll(amount);
+ mOverScrollEffect = acceleratedOverFactor(amount);
+ } else {
+ mOverScrollEffect = 0;
+ }
+
+ if (shouldZeroOverlay) {
+ mLauncherOverlay.onScrollChange(0, isRtl);
+ }
}
@Override
@@ -1261,14 +1330,11 @@ public class Workspace extends SmoothPagedView
if (mCustomContentCallbacks != null) {
mCustomContentCallbacks.onShow(false);
mCustomContentShowTime = System.currentTimeMillis();
- mLauncher.updateVoiceButtonProxyVisible(false);
}
} else if (hasCustomContent() && getNextPage() != 0 && mCustomContentShowing) {
mCustomContentShowing = false;
if (mCustomContentCallbacks != null) {
mCustomContentCallbacks.onHide();
- mLauncher.resetQSBScroll();
- mLauncher.updateVoiceButtonProxyVisible(false);
}
}
}
@@ -1711,18 +1777,6 @@ public class Workspace extends SmoothPagedView
}
}
- @Override
- protected void overScroll(float amount) {
- boolean shouldOverScroll = (amount < 0 && (!hasCustomContent() || isLayoutRtl())) ||
- (amount > 0 && (!hasCustomContent() || !isLayoutRtl()));
- if (shouldOverScroll) {
- dampedOverScroll(amount);
- mOverScrollEffect = acceleratedOverFactor(amount);
- } else {
- mOverScrollEffect = 0;
- }
- }
-
protected void onAttachedToWindow() {
super.onAttachedToWindow();
mWindowToken = getWindowToken();
@@ -2148,16 +2202,6 @@ public class Workspace extends SmoothPagedView
return -offsetFromTopEdge + mInsets.top + offsetToCenterInOverview;
}
- boolean shouldVoiceButtonProxyBeVisible() {
- if (isOnOrMovingToCustomContent()) {
- return false;
- }
- if (mState != State.NORMAL) {
- return false;
- }
- return true;
- }
-
public void updateInteractionForState() {
if (mState != State.NORMAL) {
mLauncher.onInteractionBegin();
@@ -2200,6 +2244,13 @@ public class Workspace extends SmoothPagedView
AnimatorSet anim = animated ? LauncherAnimUtils.createAnimatorSet() : null;
+ // We only want a single instance of a workspace animation to be running at once, so
+ // we cancel any incomplete transition.
+ if (mStateAnimator != null) {
+ mStateAnimator.cancel();
+ }
+ mStateAnimator = anim;
+
final State oldState = mState;
final boolean oldStateIsNormal = (oldState == State.NORMAL);
final boolean oldStateIsSpringLoaded = (oldState == State.SPRING_LOADED);
@@ -2354,10 +2405,6 @@ public class Workspace extends SmoothPagedView
.alpha(finalHotseatAndPageIndicatorAlpha).withLayer();
hotseatAlpha.addListener(new AlphaUpdateListener(hotseat));
- Animator searchBarAlpha = new LauncherViewPropertyAnimator(searchBar)
- .alpha(finalSearchBarAlpha).withLayer();
- searchBarAlpha.addListener(new AlphaUpdateListener(searchBar));
-
Animator overviewPanelAlpha = new LauncherViewPropertyAnimator(overviewPanel)
.alpha(finalOverviewPanelAlpha).withLayer();
overviewPanelAlpha.addListener(new AlphaUpdateListener(overviewPanel));
@@ -2365,11 +2412,9 @@ public class Workspace extends SmoothPagedView
// For animation optimations, we may need to provide the Launcher transition
// with a set of views on which to force build layers in certain scenarios.
hotseat.setLayerType(View.LAYER_TYPE_HARDWARE, null);
- searchBar.setLayerType(View.LAYER_TYPE_HARDWARE, null);
overviewPanel.setLayerType(View.LAYER_TYPE_HARDWARE, null);
if (layerViews != null) {
layerViews.add(hotseat);
- layerViews.add(searchBar);
layerViews.add(overviewPanel);
}
@@ -2386,13 +2431,29 @@ public class Workspace extends SmoothPagedView
overviewPanelAlpha.setDuration(duration);
pageIndicatorAlpha.setDuration(duration);
hotseatAlpha.setDuration(duration);
- searchBarAlpha.setDuration(duration);
+
+ if (searchBar != null) {
+ Animator searchBarAlpha = new LauncherViewPropertyAnimator(searchBar)
+ .alpha(finalSearchBarAlpha).withLayer();
+ searchBarAlpha.addListener(new AlphaUpdateListener(searchBar));
+ searchBar.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+ if (layerViews != null) {
+ layerViews.add(searchBar);
+ }
+ searchBarAlpha.setDuration(duration);
+ anim.play(searchBarAlpha);
+ }
anim.play(overviewPanelAlpha);
anim.play(hotseatAlpha);
- anim.play(searchBarAlpha);
anim.play(pageIndicatorAlpha);
anim.setStartDelay(delay);
+ anim.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mStateAnimator = null;
+ }
+ });
} else {
overviewPanel.setAlpha(finalOverviewPanelAlpha);
AlphaUpdateListener.updateVisibility(overviewPanel);
@@ -2402,14 +2463,15 @@ public class Workspace extends SmoothPagedView
pageIndicator.setAlpha(finalHotseatAndPageIndicatorAlpha);
AlphaUpdateListener.updateVisibility(pageIndicator);
}
- searchBar.setAlpha(finalSearchBarAlpha);
- AlphaUpdateListener.updateVisibility(searchBar);
+ if (searchBar != null) {
+ searchBar.setAlpha(finalSearchBarAlpha);
+ AlphaUpdateListener.updateVisibility(searchBar);
+ }
updateCustomContentVisibility();
setScaleX(mNewScale);
setScaleY(mNewScale);
setTranslationY(finalWorkspaceTranslationY);
}
- mLauncher.updateVoiceButtonProxyVisible(false);
if (stateIsNormal) {
animateBackgroundGradient(0f, animated);
@@ -4629,6 +4691,34 @@ public class Workspace extends SmoothPagedView
});
}
+ public void disableShortcutsByPackageName(final ArrayList<String> packages,
+ final UserHandleCompat user, final int reason) {
+ final HashSet<String> packageNames = new HashSet<String>();
+ packageNames.addAll(packages);
+
+ mapOverItems(MAP_RECURSE, new ItemOperator() {
+ @Override
+ public boolean evaluate(ItemInfo info, View v, View parent) {
+ if (info instanceof ShortcutInfo && v instanceof BubbleTextView) {
+ ShortcutInfo shortcutInfo = (ShortcutInfo) info;
+ ComponentName cn = shortcutInfo.getTargetComponent();
+ if (user.equals(shortcutInfo.user) && cn != null
+ && packageNames.contains(cn.getPackageName())) {
+ shortcutInfo.isDisabled |= reason;
+ BubbleTextView shortcut = (BubbleTextView) v;
+ shortcut.applyFromShortcutInfo(shortcutInfo, mIconCache, true, false);
+
+ if (parent != null) {
+ parent.invalidate();
+ }
+ }
+ }
+ // process all the shortcuts
+ return false;
+ }
+ });
+ }
+
// Removes ALL items that match a given package name, this is usually called when a package
// has been removed and we want to remove all components (widgets, shortcuts, apps) that
// belong to that package.
@@ -4666,20 +4756,11 @@ public class Workspace extends SmoothPagedView
removeItemsByComponentName(cns, user);
}
- // Removes items that match the application info specified, when applications are removed
- // as a part of an update, this is called to ensure that other widgets and application
- // shortcuts are not removed.
- void removeItemsByApplicationInfo(final ArrayList<AppInfo> appInfos, UserHandleCompat user) {
- // Just create a hash table of all the specific components that this will affect
- HashSet<ComponentName> cns = new HashSet<ComponentName>();
- for (AppInfo info : appInfos) {
- cns.add(info.componentName);
- }
-
- // Remove all the things
- removeItemsByComponentName(cns, user);
- }
-
+ /**
+ * Removes items that match the item info specified. When applications are removed
+ * as a part of an update, this is called to ensure that other widgets and application
+ * shortcuts are not removed.
+ */
void removeItemsByComponentName(final HashSet<ComponentName> componentNames,
final UserHandleCompat user) {
ArrayList<CellLayout> cellLayouts = getWorkspaceAndHotseatCellLayouts();
@@ -4800,118 +4881,28 @@ public class Workspace extends SmoothPagedView
}
}
- void updateShortcutsAndWidgets(ArrayList<AppInfo> apps) {
- // Break the appinfo list per user
- final HashMap<UserHandleCompat, ArrayList<AppInfo>> appsPerUser =
- new HashMap<UserHandleCompat, ArrayList<AppInfo>>();
- for (AppInfo info : apps) {
- ArrayList<AppInfo> filtered = appsPerUser.get(info.user);
- if (filtered == null) {
- filtered = new ArrayList<AppInfo>();
- appsPerUser.put(info.user, filtered);
- }
- filtered.add(info);
- }
-
- for (Map.Entry<UserHandleCompat, ArrayList<AppInfo>> entry : appsPerUser.entrySet()) {
- updateShortcutsAndWidgetsPerUser(entry.getValue(), entry.getKey());
- }
- }
-
- private void updateShortcutsAndWidgetsPerUser(ArrayList<AppInfo> apps,
- final UserHandleCompat user) {
- // Create a map of the apps to test against
- final HashMap<ComponentName, AppInfo> appsMap = new HashMap<ComponentName, AppInfo>();
- final HashSet<String> pkgNames = new HashSet<String>();
- for (AppInfo ai : apps) {
- appsMap.put(ai.componentName, ai);
- pkgNames.add(ai.componentName.getPackageName());
- }
- final HashSet<ComponentName> iconsToRemove = new HashSet<ComponentName>();
-
+ void updateShortcuts(ArrayList<ShortcutInfo> shortcuts) {
+ final HashSet<ShortcutInfo> updates = new HashSet<ShortcutInfo>(shortcuts);
mapOverItems(MAP_RECURSE, new ItemOperator() {
@Override
public boolean evaluate(ItemInfo info, View v, View parent) {
- if (info instanceof ShortcutInfo && v instanceof BubbleTextView) {
- ShortcutInfo shortcutInfo = (ShortcutInfo) info;
- ComponentName cn = shortcutInfo.getTargetComponent();
- AppInfo appInfo = appsMap.get(cn);
- if (user.equals(shortcutInfo.user) && cn != null
- && LauncherModel.isShortcutInfoUpdateable(info)
- && pkgNames.contains(cn.getPackageName())) {
- boolean promiseStateChanged = false;
- boolean infoUpdated = false;
- if (shortcutInfo.isPromise()) {
- if (shortcutInfo.hasStatusFlag(ShortcutInfo.FLAG_AUTOINTALL_ICON)) {
- // Auto install icon
- PackageManager pm = getContext().getPackageManager();
- ResolveInfo matched = pm.resolveActivity(
- new Intent(Intent.ACTION_MAIN)
- .setComponent(cn).addCategory(Intent.CATEGORY_LAUNCHER),
- PackageManager.MATCH_DEFAULT_ONLY);
- if (matched == null) {
- // Try to find the best match activity.
- Intent intent = pm.getLaunchIntentForPackage(
- cn.getPackageName());
- if (intent != null) {
- cn = intent.getComponent();
- appInfo = appsMap.get(cn);
- }
-
- if ((intent == null) || (appsMap == null)) {
- // Could not find a default activity. Remove this item.
- iconsToRemove.add(shortcutInfo.getTargetComponent());
-
- // process next shortcut.
- return false;
- }
- shortcutInfo.promisedIntent = intent;
- }
- }
-
- // Restore the shortcut.
- shortcutInfo.intent = shortcutInfo.promisedIntent;
- shortcutInfo.promisedIntent = null;
- shortcutInfo.status &= ~ShortcutInfo.FLAG_RESTORED_ICON
- & ~ShortcutInfo.FLAG_AUTOINTALL_ICON
- & ~ShortcutInfo.FLAG_INSTALL_SESSION_ACTIVE;
-
- promiseStateChanged = true;
- infoUpdated = true;
- shortcutInfo.updateIcon(mIconCache);
- LauncherModel.updateItemInDatabase(getContext(), shortcutInfo);
- }
-
-
- if (appInfo != null) {
- shortcutInfo.updateIcon(mIconCache);
- shortcutInfo.title = appInfo.title.toString();
- shortcutInfo.contentDescription = appInfo.contentDescription;
- infoUpdated = true;
- }
-
- if (infoUpdated) {
- BubbleTextView shortcut = (BubbleTextView) v;
- shortcut.applyFromShortcutInfo(shortcutInfo,
- mIconCache, true, promiseStateChanged);
-
- if (parent != null) {
- parent.invalidate();
- }
- }
+ if (info instanceof ShortcutInfo && v instanceof BubbleTextView &&
+ updates.contains(info)) {
+ ShortcutInfo si = (ShortcutInfo) info;
+ BubbleTextView shortcut = (BubbleTextView) v;
+ boolean oldPromiseState = shortcut.getCompoundDrawables()[1]
+ instanceof PreloadIconDrawable;
+ shortcut.applyFromShortcutInfo(si, mIconCache, true,
+ si.isPromise() != oldPromiseState);
+
+ if (parent != null) {
+ parent.invalidate();
}
}
// process all the shortcuts
return false;
}
});
-
- if (!iconsToRemove.isEmpty()) {
- removeItemsByComponentName(iconsToRemove, user);
- }
- if (user.equals(UserHandleCompat.myUserHandle())) {
- restorePendingWidgets(pkgNames);
- }
}
public void removeAbandonedPromise(String packageName, UserHandleCompat user) {
@@ -4954,9 +4945,11 @@ public class Workspace extends SmoothPagedView
}
public void updatePackageState(ArrayList<PackageInstallInfo> installInfos) {
- HashSet<String> completedPackages = new HashSet<String>();
-
for (final PackageInstallInfo installInfo : installInfos) {
+ if (installInfo.state == PackageInstallerCompat.STATUS_INSTALLED) {
+ continue;
+ }
+
mapOverItems(MAP_RECURSE, new ItemOperator() {
@Override
public boolean evaluate(ItemInfo info, View v, View parent) {
@@ -4984,42 +4977,10 @@ public class Workspace extends SmoothPagedView
return false;
}
});
-
- if (installInfo.state == PackageInstallerCompat.STATUS_INSTALLED) {
- completedPackages.add(installInfo.packageName);
- }
- }
-
- // Note that package states are sent only for myUser
- if (!completedPackages.isEmpty()) {
- restorePendingWidgets(completedPackages);
}
}
- private void restorePendingWidgets(final Set<String> installedPackaged) {
- final ArrayList<LauncherAppWidgetInfo> changedInfo = new ArrayList<LauncherAppWidgetInfo>();
-
- // Iterate non recursively as widgets can't be inside a folder.
- mapOverItems(MAP_NO_RECURSE, new ItemOperator() {
-
- @Override
- public boolean evaluate(ItemInfo info, View v, View parent) {
- if (info instanceof LauncherAppWidgetInfo) {
- LauncherAppWidgetInfo widgetInfo = (LauncherAppWidgetInfo) info;
- if (widgetInfo.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY)
- && installedPackaged.contains(widgetInfo.providerName.getPackageName())) {
-
- changedInfo.add(widgetInfo);
-
- // Remove the provider not ready flag
- widgetInfo.restoreStatus &= ~LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY;
- LauncherModel.updateItemInDatabase(getContext(), widgetInfo);
- }
- }
- // process all the widget
- return false;
- }
- });
+ void widgetsRestored(ArrayList<LauncherAppWidgetInfo> changedInfo) {
if (!changedInfo.isEmpty()) {
DeferredWidgetRefresh widgetRefresh = new DeferredWidgetRefresh(changedInfo,
mLauncher.getAppWidgetHost());
@@ -5029,6 +4990,13 @@ public class Workspace extends SmoothPagedView
widgetRefresh.run();
} else {
// widgetRefresh will automatically run when the packages are updated.
+ // For now just update the progress bars
+ for (LauncherAppWidgetInfo info : changedInfo) {
+ if (info.hostView instanceof PendingAppWidgetHostView) {
+ info.installProgress = 100;
+ ((PendingAppWidgetHostView) info.hostView).applyState();
+ }
+ }
}
}
}
diff --git a/src/com/android/launcher3/compat/AppWidgetManagerCompatVL.java b/src/com/android/launcher3/compat/AppWidgetManagerCompatVL.java
index c3853ab62..03d43a6f2 100644
--- a/src/com/android/launcher3/compat/AppWidgetManagerCompatVL.java
+++ b/src/com/android/launcher3/compat/AppWidgetManagerCompatVL.java
@@ -43,7 +43,7 @@ import com.android.launcher3.R;
import java.util.ArrayList;
import java.util.List;
-@TargetApi(Build.VERSION_CODES.L)
+@TargetApi(Build.VERSION_CODES.LOLLIPOP)
class AppWidgetManagerCompatVL extends AppWidgetManagerCompat {
private final UserManager mUserManager;
diff --git a/src/com/android/launcher3/compat/LauncherAppsCompat.java b/src/com/android/launcher3/compat/LauncherAppsCompat.java
index 6efcc00fd..5858bc8b9 100644
--- a/src/com/android/launcher3/compat/LauncherAppsCompat.java
+++ b/src/com/android/launcher3/compat/LauncherAppsCompat.java
@@ -19,8 +19,10 @@ package com.android.launcher3.compat;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
import android.graphics.Rect;
-import android.os.Build;
import android.os.Bundle;
import com.android.launcher3.Utilities;
@@ -73,4 +75,13 @@ public abstract class LauncherAppsCompat {
public abstract boolean isPackageEnabledForProfile(String packageName, UserHandleCompat user);
public abstract boolean isActivityEnabledForProfile(ComponentName component,
UserHandleCompat user);
+
+ public boolean isAppEnabled(PackageManager pm, String packageName, int flags) {
+ try {
+ ApplicationInfo info = pm.getApplicationInfo(packageName, flags);
+ return info != null && info.enabled;
+ } catch (NameNotFoundException e) {
+ return false;
+ }
+ }
} \ No newline at end of file
diff --git a/src/com/android/launcher3/compat/LauncherAppsCompatV16.java b/src/com/android/launcher3/compat/LauncherAppsCompatV16.java
index 7e5e6bf2c..e47b9a58d 100644
--- a/src/com/android/launcher3/compat/LauncherAppsCompatV16.java
+++ b/src/com/android/launcher3/compat/LauncherAppsCompatV16.java
@@ -22,7 +22,6 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ActivityInfo;
-import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
@@ -112,12 +111,7 @@ public class LauncherAppsCompatV16 extends LauncherAppsCompat {
}
public boolean isPackageEnabledForProfile(String packageName, UserHandleCompat user) {
- try {
- PackageInfo info = mPm.getPackageInfo(packageName, 0);
- return info != null && info.applicationInfo.enabled;
- } catch (NameNotFoundException e) {
- return false;
- }
+ return isAppEnabled(mPm, packageName, 0);
}
public boolean isActivityEnabledForProfile(ComponentName component, UserHandleCompat user) {
@@ -198,8 +192,13 @@ public class LauncherAppsCompatV16 extends LauncherAppsCompat {
callback.onPackagesAvailable(packages, user, replacing);
}
} else if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(action)) {
- final boolean replacing = intent.getBooleanExtra(Intent.EXTRA_REPLACING,
- Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT);
+ // This intent is broadcasted when moving a package or mounting/un-mounting
+ // external storage.
+ // However on Kitkat this is also sent when a package is being updated, and
+ // contains an extra Intent.EXTRA_REPLACING=true for that case.
+ // Using false as default for Intent.EXTRA_REPLACING gives correct value on
+ // lower devices as the intent is not sent when the app is updating/replacing.
+ final boolean replacing = intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
String[] packages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
for (OnAppsChangedCallbackCompat callback : getCallbacks()) {
callback.onPackagesUnavailable(packages, user, replacing);
diff --git a/src/com/android/launcher3/compat/PackageInstallerCompatVL.java b/src/com/android/launcher3/compat/PackageInstallerCompatVL.java
index 16ad3792a..601f04cea 100644
--- a/src/com/android/launcher3/compat/PackageInstallerCompatVL.java
+++ b/src/com/android/launcher3/compat/PackageInstallerCompatVL.java
@@ -20,6 +20,7 @@ import android.content.Context;
import android.content.pm.PackageInstaller;
import android.content.pm.PackageInstaller.SessionCallback;
import android.content.pm.PackageInstaller.SessionInfo;
+import android.os.Handler;
import android.util.Log;
import android.util.SparseArray;
@@ -29,15 +30,18 @@ import com.android.launcher3.LauncherAppState;
import java.util.ArrayList;
import java.util.HashSet;
-public class PackageInstallerCompatVL extends PackageInstallerCompat {
+public class PackageInstallerCompatVL extends PackageInstallerCompat implements Runnable {
private static final String TAG = "PackageInstallerCompatVL";
private static final boolean DEBUG = false;
+ // All updates to these sets must happen on the {@link #mWorker} thread.
private final SparseArray<SessionInfo> mPendingReplays = new SparseArray<SessionInfo>();
private final HashSet<String> mPendingBadgeUpdates = new HashSet<String>();
+
private final PackageInstaller mInstaller;
private final IconCache mCache;
+ private final Handler mWorker;
private boolean mResumed;
private boolean mBound;
@@ -46,16 +50,23 @@ public class PackageInstallerCompatVL extends PackageInstallerCompat {
mInstaller = context.getPackageManager().getPackageInstaller();
LauncherAppState.setApplicationContext(context.getApplicationContext());
mCache = LauncherAppState.getInstance().getIconCache();
+ mWorker = new Handler();
mResumed = false;
mBound = false;
- mInstaller.registerSessionCallback(mCallback);
+ mInstaller.registerSessionCallback(mCallback, mWorker);
// On start, send updates for all active sessions
- for (SessionInfo info : mInstaller.getAllSessions()) {
- mPendingReplays.append(info.getSessionId(), info);
- }
+ mWorker.post(new Runnable() {
+
+ @Override
+ public void run() {
+ for (SessionInfo info : mInstaller.getAllSessions()) {
+ mPendingReplays.append(info.getSessionId(), info);
+ }
+ }
+ });
}
@Override
@@ -81,12 +92,13 @@ public class PackageInstallerCompatVL extends PackageInstallerCompat {
@Override
public void onStop() {
+ mInstaller.unregisterSessionCallback(mCallback);
}
@Override
public void onFinishBind() {
mBound = true;
- replayUpdates(null);
+ mWorker.post(this);
}
@Override
@@ -97,7 +109,7 @@ public class PackageInstallerCompatVL extends PackageInstallerCompat {
@Override
public void onResume() {
mResumed = true;
- replayUpdates(null);
+ mWorker.post(this);
}
@Override
@@ -105,13 +117,19 @@ public class PackageInstallerCompatVL extends PackageInstallerCompat {
// No op
}
+ @Override
+ public void run() {
+ // Called on mWorker thread.
+ replayUpdates(null);
+ }
+
private void replayUpdates(PackageInstallInfo newInfo) {
if (DEBUG) Log.d(TAG, "updates resumed");
if (!mResumed || !mBound) {
// Not yet ready
return;
}
- if ((mPendingReplays.size() == 0) && (newInfo == null) && mPendingBadgeUpdates.isEmpty()) {
+ if ((mPendingReplays.size() == 0) && (newInfo == null)) {
// Nothing to update
return;
}