diff options
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 Binary files differdeleted file mode 100644 index c72d6a2c6..000000000 --- a/WallpaperPicker/res/drawable-hdpi/tile_picker_focused.9.png +++ /dev/null diff --git a/WallpaperPicker/res/drawable-hdpi/tile_picker_pressed.9.png b/WallpaperPicker/res/drawable-hdpi/tile_picker_pressed.9.png Binary files differdeleted file mode 100644 index 44c65ac3c..000000000 --- a/WallpaperPicker/res/drawable-hdpi/tile_picker_pressed.9.png +++ /dev/null diff --git a/WallpaperPicker/res/drawable-hdpi/tile_picker_selected.9.png b/WallpaperPicker/res/drawable-hdpi/tile_picker_selected.9.png Binary files differdeleted file mode 100644 index 461bacbcb..000000000 --- a/WallpaperPicker/res/drawable-hdpi/tile_picker_selected.9.png +++ /dev/null diff --git a/WallpaperPicker/res/drawable-mdpi/tile_picker_focused.9.png b/WallpaperPicker/res/drawable-mdpi/tile_picker_focused.9.png Binary files differdeleted file mode 100644 index 13b325b87..000000000 --- a/WallpaperPicker/res/drawable-mdpi/tile_picker_focused.9.png +++ /dev/null diff --git a/WallpaperPicker/res/drawable-mdpi/tile_picker_pressed.9.png b/WallpaperPicker/res/drawable-mdpi/tile_picker_pressed.9.png Binary files differdeleted file mode 100644 index 4e8196d36..000000000 --- a/WallpaperPicker/res/drawable-mdpi/tile_picker_pressed.9.png +++ /dev/null diff --git a/WallpaperPicker/res/drawable-mdpi/tile_picker_selected.9.png b/WallpaperPicker/res/drawable-mdpi/tile_picker_selected.9.png Binary files differdeleted file mode 100644 index eee69ec6d..000000000 --- a/WallpaperPicker/res/drawable-mdpi/tile_picker_selected.9.png +++ /dev/null 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 Binary files differdeleted file mode 100644 index 279e85963..000000000 --- a/WallpaperPicker/res/drawable-xhdpi/tile_picker_focused.9.png +++ /dev/null diff --git a/WallpaperPicker/res/drawable-xhdpi/tile_picker_pressed.9.png b/WallpaperPicker/res/drawable-xhdpi/tile_picker_pressed.9.png Binary files differdeleted file mode 100644 index abe0e0080..000000000 --- a/WallpaperPicker/res/drawable-xhdpi/tile_picker_pressed.9.png +++ /dev/null diff --git a/WallpaperPicker/res/drawable-xhdpi/tile_picker_selected.9.png b/WallpaperPicker/res/drawable-xhdpi/tile_picker_selected.9.png Binary files differdeleted file mode 100644 index b047591ac..000000000 --- a/WallpaperPicker/res/drawable-xhdpi/tile_picker_selected.9.png +++ /dev/null diff --git a/WallpaperPicker/res/drawable-xxhdpi/tile_picker_focused.9.png b/WallpaperPicker/res/drawable-xxhdpi/tile_picker_focused.9.png Binary files differdeleted file mode 100644 index 1004c14b8..000000000 --- a/WallpaperPicker/res/drawable-xxhdpi/tile_picker_focused.9.png +++ /dev/null diff --git a/WallpaperPicker/res/drawable-xxhdpi/tile_picker_pressed.9.png b/WallpaperPicker/res/drawable-xxhdpi/tile_picker_pressed.9.png Binary files differdeleted file mode 100644 index 9658444a1..000000000 --- a/WallpaperPicker/res/drawable-xxhdpi/tile_picker_pressed.9.png +++ /dev/null diff --git a/WallpaperPicker/res/drawable-xxhdpi/tile_picker_selected.9.png b/WallpaperPicker/res/drawable-xxhdpi/tile_picker_selected.9.png Binary files differdeleted file mode 100644 index a3cd30369..000000000 --- a/WallpaperPicker/res/drawable-xxhdpi/tile_picker_selected.9.png +++ /dev/null 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 Binary files differdeleted file mode 100644 index bd4f6dfbc..000000000 --- a/res/drawable-hdpi/hand.png +++ /dev/null diff --git a/res/drawable-hdpi/ic_home_search_normal_holo.png b/res/drawable-hdpi/ic_home_search_normal_holo.png Binary files differdeleted file mode 100644 index 3f64d6823..000000000 --- a/res/drawable-hdpi/ic_home_search_normal_holo.png +++ /dev/null diff --git a/res/drawable-hdpi/ic_home_voice_search_holo.png b/res/drawable-hdpi/ic_home_voice_search_holo.png Binary files differdeleted file mode 100644 index dae54464a..000000000 --- a/res/drawable-hdpi/ic_home_voice_search_holo.png +++ /dev/null diff --git a/res/drawable-hdpi/ic_pageindicator_current.png b/res/drawable-hdpi/ic_pageindicator_current.png Binary files differindex 2e841f5f5..283f44d37 100644 --- a/res/drawable-hdpi/ic_pageindicator_current.png +++ b/res/drawable-hdpi/ic_pageindicator_current.png diff --git a/res/drawable-hdpi/ic_pageindicator_default.png b/res/drawable-hdpi/ic_pageindicator_default.png Binary files differindex 07ab94865..47b998967 100644 --- a/res/drawable-hdpi/ic_pageindicator_default.png +++ b/res/drawable-hdpi/ic_pageindicator_default.png diff --git a/res/drawable-hdpi/search_frame.9.png b/res/drawable-hdpi/search_frame.9.png Binary files differdeleted file mode 100644 index 15ca1f4e6..000000000 --- a/res/drawable-hdpi/search_frame.9.png +++ /dev/null diff --git a/res/drawable-hdpi/tab_selected_focused_holo.9.png b/res/drawable-hdpi/tab_selected_focused_holo.9.png Binary files differdeleted file mode 100644 index 673e3bf10..000000000 --- a/res/drawable-hdpi/tab_selected_focused_holo.9.png +++ /dev/null diff --git a/res/drawable-hdpi/tab_selected_holo.9.png b/res/drawable-hdpi/tab_selected_holo.9.png Binary files differdeleted file mode 100644 index d57df98b5..000000000 --- a/res/drawable-hdpi/tab_selected_holo.9.png +++ /dev/null diff --git a/res/drawable-hdpi/tab_selected_pressed_focused_holo.9.png b/res/drawable-hdpi/tab_selected_pressed_focused_holo.9.png Binary files differdeleted file mode 100644 index 4b312d9e3..000000000 --- a/res/drawable-hdpi/tab_selected_pressed_focused_holo.9.png +++ /dev/null diff --git a/res/drawable-hdpi/tab_selected_pressed_holo.9.png b/res/drawable-hdpi/tab_selected_pressed_holo.9.png Binary files differdeleted file mode 100644 index 6278eef47..000000000 --- a/res/drawable-hdpi/tab_selected_pressed_holo.9.png +++ /dev/null diff --git a/res/drawable-hdpi/tab_unselected_focused_holo.9.png b/res/drawable-hdpi/tab_unselected_focused_holo.9.png Binary files differdeleted file mode 100644 index 294991d79..000000000 --- a/res/drawable-hdpi/tab_unselected_focused_holo.9.png +++ /dev/null diff --git a/res/drawable-hdpi/tab_unselected_holo.9.png b/res/drawable-hdpi/tab_unselected_holo.9.png Binary files differdeleted file mode 100644 index 19532ab10..000000000 --- a/res/drawable-hdpi/tab_unselected_holo.9.png +++ /dev/null diff --git a/res/drawable-hdpi/tab_unselected_pressed_focused_holo.9.png b/res/drawable-hdpi/tab_unselected_pressed_focused_holo.9.png Binary files differdeleted file mode 100644 index 5140b3523..000000000 --- a/res/drawable-hdpi/tab_unselected_pressed_focused_holo.9.png +++ /dev/null diff --git a/res/drawable-hdpi/tab_unselected_pressed_holo.9.png b/res/drawable-hdpi/tab_unselected_pressed_holo.9.png Binary files differdeleted file mode 100644 index aadc6f87b..000000000 --- a/res/drawable-hdpi/tab_unselected_pressed_holo.9.png +++ /dev/null diff --git a/res/drawable-land-hdpi/ic_home_voice_search_holo.png b/res/drawable-land-hdpi/ic_home_voice_search_holo.png Binary files differdeleted file mode 100644 index 5a7fc99e4..000000000 --- a/res/drawable-land-hdpi/ic_home_voice_search_holo.png +++ /dev/null diff --git a/res/drawable-land-mdpi/ic_home_voice_search_holo.png b/res/drawable-land-mdpi/ic_home_voice_search_holo.png Binary files differdeleted file mode 100644 index ee7dde52c..000000000 --- a/res/drawable-land-mdpi/ic_home_voice_search_holo.png +++ /dev/null diff --git a/res/drawable-land-xhdpi/ic_home_voice_search_holo.png b/res/drawable-land-xhdpi/ic_home_voice_search_holo.png Binary files differdeleted file mode 100644 index 56bbbbb06..000000000 --- a/res/drawable-land-xhdpi/ic_home_voice_search_holo.png +++ /dev/null diff --git a/res/drawable-land-xxhdpi/ic_home_voice_search_holo.png b/res/drawable-land-xxhdpi/ic_home_voice_search_holo.png Binary files differdeleted file mode 100644 index 6ea7368be..000000000 --- a/res/drawable-land-xxhdpi/ic_home_voice_search_holo.png +++ /dev/null diff --git a/res/drawable-mdpi/hand.png b/res/drawable-mdpi/hand.png Binary files differdeleted file mode 100644 index fe5a035de..000000000 --- a/res/drawable-mdpi/hand.png +++ /dev/null diff --git a/res/drawable-mdpi/ic_home_search_normal_holo.png b/res/drawable-mdpi/ic_home_search_normal_holo.png Binary files differdeleted file mode 100644 index 7367c380c..000000000 --- a/res/drawable-mdpi/ic_home_search_normal_holo.png +++ /dev/null diff --git a/res/drawable-mdpi/ic_home_voice_search_holo.png b/res/drawable-mdpi/ic_home_voice_search_holo.png Binary files differdeleted file mode 100644 index f211a7b9c..000000000 --- a/res/drawable-mdpi/ic_home_voice_search_holo.png +++ /dev/null diff --git a/res/drawable-mdpi/ic_pageindicator_current.png b/res/drawable-mdpi/ic_pageindicator_current.png Binary files differindex 08f43b4c1..b41e1bb67 100644 --- a/res/drawable-mdpi/ic_pageindicator_current.png +++ b/res/drawable-mdpi/ic_pageindicator_current.png diff --git a/res/drawable-mdpi/ic_pageindicator_default.png b/res/drawable-mdpi/ic_pageindicator_default.png Binary files differindex 635be4a37..e36c25cf1 100644 --- a/res/drawable-mdpi/ic_pageindicator_default.png +++ b/res/drawable-mdpi/ic_pageindicator_default.png diff --git a/res/drawable-mdpi/search_frame.9.png b/res/drawable-mdpi/search_frame.9.png Binary files differdeleted file mode 100644 index 058905bdb..000000000 --- a/res/drawable-mdpi/search_frame.9.png +++ /dev/null diff --git a/res/drawable-mdpi/tab_selected_focused_holo.9.png b/res/drawable-mdpi/tab_selected_focused_holo.9.png Binary files differdeleted file mode 100644 index c9972e74b..000000000 --- a/res/drawable-mdpi/tab_selected_focused_holo.9.png +++ /dev/null diff --git a/res/drawable-mdpi/tab_selected_holo.9.png b/res/drawable-mdpi/tab_selected_holo.9.png Binary files differdeleted file mode 100644 index 587337caf..000000000 --- a/res/drawable-mdpi/tab_selected_holo.9.png +++ /dev/null diff --git a/res/drawable-mdpi/tab_selected_pressed_focused_holo.9.png b/res/drawable-mdpi/tab_selected_pressed_focused_holo.9.png Binary files differdeleted file mode 100644 index 284f5344a..000000000 --- a/res/drawable-mdpi/tab_selected_pressed_focused_holo.9.png +++ /dev/null diff --git a/res/drawable-mdpi/tab_selected_pressed_holo.9.png b/res/drawable-mdpi/tab_selected_pressed_holo.9.png Binary files differdeleted file mode 100644 index 155c4fc75..000000000 --- a/res/drawable-mdpi/tab_selected_pressed_holo.9.png +++ /dev/null diff --git a/res/drawable-mdpi/tab_unselected_focused_holo.9.png b/res/drawable-mdpi/tab_unselected_focused_holo.9.png Binary files differdeleted file mode 100644 index f0cecd183..000000000 --- a/res/drawable-mdpi/tab_unselected_focused_holo.9.png +++ /dev/null diff --git a/res/drawable-mdpi/tab_unselected_holo.9.png b/res/drawable-mdpi/tab_unselected_holo.9.png Binary files differdeleted file mode 100644 index a2dbf42b7..000000000 --- a/res/drawable-mdpi/tab_unselected_holo.9.png +++ /dev/null diff --git a/res/drawable-mdpi/tab_unselected_pressed_focused_holo.9.png b/res/drawable-mdpi/tab_unselected_pressed_focused_holo.9.png Binary files differdeleted file mode 100644 index f1a2819c5..000000000 --- a/res/drawable-mdpi/tab_unselected_pressed_focused_holo.9.png +++ /dev/null diff --git a/res/drawable-mdpi/tab_unselected_pressed_holo.9.png b/res/drawable-mdpi/tab_unselected_pressed_holo.9.png Binary files differdeleted file mode 100644 index b1223fe3c..000000000 --- a/res/drawable-mdpi/tab_unselected_pressed_holo.9.png +++ /dev/null diff --git a/res/drawable-xhdpi/hand.png b/res/drawable-xhdpi/hand.png Binary files differdeleted file mode 100644 index 35b678c89..000000000 --- a/res/drawable-xhdpi/hand.png +++ /dev/null diff --git a/res/drawable-xhdpi/ic_home_search_normal_holo.png b/res/drawable-xhdpi/ic_home_search_normal_holo.png Binary files differdeleted file mode 100644 index 0fe1cd133..000000000 --- a/res/drawable-xhdpi/ic_home_search_normal_holo.png +++ /dev/null diff --git a/res/drawable-xhdpi/ic_home_voice_search_holo.png b/res/drawable-xhdpi/ic_home_voice_search_holo.png Binary files differdeleted file mode 100644 index 1fc5cc8bb..000000000 --- a/res/drawable-xhdpi/ic_home_voice_search_holo.png +++ /dev/null diff --git a/res/drawable-xhdpi/ic_pageindicator_current.png b/res/drawable-xhdpi/ic_pageindicator_current.png Binary files differindex 0e9a52f6d..8fa774dee 100644 --- a/res/drawable-xhdpi/ic_pageindicator_current.png +++ b/res/drawable-xhdpi/ic_pageindicator_current.png diff --git a/res/drawable-xhdpi/ic_pageindicator_default.png b/res/drawable-xhdpi/ic_pageindicator_default.png Binary files differindex d0f14cdfb..8eb5eb08d 100644 --- a/res/drawable-xhdpi/ic_pageindicator_default.png +++ b/res/drawable-xhdpi/ic_pageindicator_default.png diff --git a/res/drawable-xhdpi/search_frame.9.png b/res/drawable-xhdpi/search_frame.9.png Binary files differdeleted file mode 100644 index 32a07143e..000000000 --- a/res/drawable-xhdpi/search_frame.9.png +++ /dev/null diff --git a/res/drawable-xhdpi/tab_selected_focused_holo.9.png b/res/drawable-xhdpi/tab_selected_focused_holo.9.png Binary files differdeleted file mode 100644 index 03cfb0945..000000000 --- a/res/drawable-xhdpi/tab_selected_focused_holo.9.png +++ /dev/null diff --git a/res/drawable-xhdpi/tab_selected_holo.9.png b/res/drawable-xhdpi/tab_selected_holo.9.png Binary files differdeleted file mode 100644 index e4229f26b..000000000 --- a/res/drawable-xhdpi/tab_selected_holo.9.png +++ /dev/null diff --git a/res/drawable-xhdpi/tab_selected_pressed_focused_holo.9.png b/res/drawable-xhdpi/tab_selected_pressed_focused_holo.9.png Binary files differdeleted file mode 100644 index 24127117f..000000000 --- a/res/drawable-xhdpi/tab_selected_pressed_focused_holo.9.png +++ /dev/null diff --git a/res/drawable-xhdpi/tab_selected_pressed_holo.9.png b/res/drawable-xhdpi/tab_selected_pressed_holo.9.png Binary files differdeleted file mode 100644 index e862cb121..000000000 --- a/res/drawable-xhdpi/tab_selected_pressed_holo.9.png +++ /dev/null diff --git a/res/drawable-xhdpi/tab_unselected_focused_holo.9.png b/res/drawable-xhdpi/tab_unselected_focused_holo.9.png Binary files differdeleted file mode 100644 index f3a5cbde8..000000000 --- a/res/drawable-xhdpi/tab_unselected_focused_holo.9.png +++ /dev/null diff --git a/res/drawable-xhdpi/tab_unselected_holo.9.png b/res/drawable-xhdpi/tab_unselected_holo.9.png Binary files differdeleted file mode 100644 index 946517378..000000000 --- a/res/drawable-xhdpi/tab_unselected_holo.9.png +++ /dev/null diff --git a/res/drawable-xhdpi/tab_unselected_pressed_focused_holo.9.png b/res/drawable-xhdpi/tab_unselected_pressed_focused_holo.9.png Binary files differdeleted file mode 100644 index 16536003f..000000000 --- a/res/drawable-xhdpi/tab_unselected_pressed_focused_holo.9.png +++ /dev/null diff --git a/res/drawable-xhdpi/tab_unselected_pressed_holo.9.png b/res/drawable-xhdpi/tab_unselected_pressed_holo.9.png Binary files differdeleted file mode 100644 index f1eb67323..000000000 --- a/res/drawable-xhdpi/tab_unselected_pressed_holo.9.png +++ /dev/null diff --git a/res/drawable-xxhdpi/hand.png b/res/drawable-xxhdpi/hand.png Binary files differdeleted file mode 100644 index 88c2a882c..000000000 --- a/res/drawable-xxhdpi/hand.png +++ /dev/null diff --git a/res/drawable-xxhdpi/ic_home_search_normal_holo.png b/res/drawable-xxhdpi/ic_home_search_normal_holo.png Binary files differdeleted file mode 100644 index a9523d3cc..000000000 --- a/res/drawable-xxhdpi/ic_home_search_normal_holo.png +++ /dev/null diff --git a/res/drawable-xxhdpi/ic_home_voice_search_holo.png b/res/drawable-xxhdpi/ic_home_voice_search_holo.png Binary files differdeleted file mode 100644 index c9c0b50bd..000000000 --- a/res/drawable-xxhdpi/ic_home_voice_search_holo.png +++ /dev/null diff --git a/res/drawable-xxhdpi/ic_pageindicator_current.png b/res/drawable-xxhdpi/ic_pageindicator_current.png Binary files differindex b74e92ea7..22b290e69 100644 --- a/res/drawable-xxhdpi/ic_pageindicator_current.png +++ b/res/drawable-xxhdpi/ic_pageindicator_current.png diff --git a/res/drawable-xxhdpi/ic_pageindicator_default.png b/res/drawable-xxhdpi/ic_pageindicator_default.png Binary files differindex e362ece71..e608cae30 100644 --- a/res/drawable-xxhdpi/ic_pageindicator_default.png +++ b/res/drawable-xxhdpi/ic_pageindicator_default.png diff --git a/res/drawable-xxhdpi/search_bg_panel.9.png b/res/drawable-xxhdpi/search_bg_panel.9.png Binary files differdeleted file mode 100644 index 85cae17bc..000000000 --- a/res/drawable-xxhdpi/search_bg_panel.9.png +++ /dev/null diff --git a/res/drawable-xxhdpi/search_frame.9.png b/res/drawable-xxhdpi/search_frame.9.png Binary files differdeleted file mode 100644 index f297bf19c..000000000 --- a/res/drawable-xxhdpi/search_frame.9.png +++ /dev/null diff --git a/res/drawable-xxhdpi/tab_selected_focused_holo.9.png b/res/drawable-xxhdpi/tab_selected_focused_holo.9.png Binary files differdeleted file mode 100644 index 2400c65d5..000000000 --- a/res/drawable-xxhdpi/tab_selected_focused_holo.9.png +++ /dev/null diff --git a/res/drawable-xxhdpi/tab_selected_holo.9.png b/res/drawable-xxhdpi/tab_selected_holo.9.png Binary files differdeleted file mode 100644 index 5067cbbfe..000000000 --- a/res/drawable-xxhdpi/tab_selected_holo.9.png +++ /dev/null diff --git a/res/drawable-xxhdpi/tab_selected_pressed_holo.9.png b/res/drawable-xxhdpi/tab_selected_pressed_holo.9.png Binary files differdeleted file mode 100644 index 84c246da4..000000000 --- a/res/drawable-xxhdpi/tab_selected_pressed_holo.9.png +++ /dev/null diff --git a/res/drawable-xxhdpi/tab_unselected_focused_holo.9.png b/res/drawable-xxhdpi/tab_unselected_focused_holo.9.png Binary files differdeleted file mode 100644 index 939e0c3e0..000000000 --- a/res/drawable-xxhdpi/tab_unselected_focused_holo.9.png +++ /dev/null diff --git a/res/drawable-xxhdpi/tab_unselected_holo.9.png b/res/drawable-xxhdpi/tab_unselected_holo.9.png Binary files differdeleted file mode 100644 index 62ca6cf84..000000000 --- a/res/drawable-xxhdpi/tab_unselected_holo.9.png +++ /dev/null diff --git a/res/drawable-xxhdpi/tab_unselected_pressed_holo.9.png b/res/drawable-xxhdpi/tab_unselected_pressed_holo.9.png Binary files differdeleted file mode 100644 index 58ac0d649..000000000 --- a/res/drawable-xxhdpi/tab_unselected_pressed_holo.9.png +++ /dev/null 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 Binary files differdeleted file mode 100644 index b9aa101ad..000000000 --- a/res/mipmap-hdpi/ic_launcher_application.png +++ /dev/null diff --git a/res/mipmap-mdpi/ic_launcher_application.png b/res/mipmap-mdpi/ic_launcher_application.png Binary files differdeleted file mode 100644 index 4771b855f..000000000 --- a/res/mipmap-mdpi/ic_launcher_application.png +++ /dev/null diff --git a/res/mipmap-xhdpi/ic_launcher_application.png b/res/mipmap-xhdpi/ic_launcher_application.png Binary files differdeleted file mode 100644 index 932f0f791..000000000 --- a/res/mipmap-xhdpi/ic_launcher_application.png +++ /dev/null diff --git a/res/mipmap-xxhdpi/ic_launcher_application.png b/res/mipmap-xxhdpi/ic_launcher_application.png Binary files differdeleted file mode 100644 index 7fc739aaf..000000000 --- a/res/mipmap-xxhdpi/ic_launcher_application.png +++ /dev/null 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 & 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 & 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">"ប៉ះ & សង្កត់ ដើម្បីជ្រើសធាតុក្រាហ្វិក។"</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">"ವಿಜೆಟ್ ಅನ್ನು ಆರಿಸಿಕೊಳ್ಳಲು ಸ್ಪರ್ಶಿಸಿ & ಹಿಡಿದುಕೊಳ್ಳಿ."</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-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">"Тушкагаздар, виджеттер & жөндөөлөр"</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">"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 & 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">"နောက်ခံများ၊ ဝီဂျက်များ& ဆက်တင်များ"</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> - <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">"விட்ஜெட்டைத் தேர்வுசெய்ய தொட்டுப் & பிடிக்கவும்."</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">"வால்பேப்பர், விட்ஜெட்கள் மற்றும் அமைப்புகளை நிர்வகிப்பதற்கு பின்புலத்தைத் தொட்டுப் & பிடிக்கவும்."</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="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">"విడ్జెట్ను ఎంచుకోవడానికి తాకి & నొక్కి పెట్టండి."</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-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 & 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; } |