keep history after reset to ub-now-lunchbox-release@1069658 am: 2b8dbe3a5f am: 319e21ec62
am: ce566c0e93
* commit 'ce566c0e93436dd819e6910f08bf7575f20c2a19':
Import translations. DO NOT MERGE
Fix overlapping pages (issue 12551580)
Properly saving migration cling keys.
Tightening migration conditions. (Bug 11973614)
Import translations. DO NOT MERGE
Fix build
Import translations. DO NOT MERGE
Initial empty repository
Import translations. DO NOT MERGE
Import translations. DO NOT MERGE
override Launcher2 (aosp)
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 591d9b6..fb7ac3f 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -88,7 +88,25 @@
android:stateNotNeeded="true"
android:theme="@style/Theme"
android:windowSoftInputMode="adjustPan"
- android:screenOrientation="nosensor">
+ android:screenOrientation="nosensor"
+ android:enabled="true">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.HOME" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <category android:name="android.intent.category.MONKEY"/>
+ </intent-filter>
+ </activity>
+
+ <activity
+ android:name="com.android.launcher3.LauncherExtension"
+ android:launchMode="singleTask"
+ android:clearTaskOnLaunch="true"
+ android:stateNotNeeded="true"
+ android:theme="@style/Theme"
+ android:windowSoftInputMode="adjustPan"
+ android:screenOrientation="nosensor"
+ android:enabled="false">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.HOME" />
diff --git a/WallpaperPicker/res/drawable-hdpi/tile_picker_focused.9.png b/WallpaperPicker/res/drawable-hdpi/tile_picker_focused.9.png
deleted file mode 100644
index c72d6a2..0000000
--- a/WallpaperPicker/res/drawable-hdpi/tile_picker_focused.9.png
+++ /dev/null
Binary files differ
diff --git a/WallpaperPicker/res/drawable-hdpi/tile_picker_pressed.9.png b/WallpaperPicker/res/drawable-hdpi/tile_picker_pressed.9.png
deleted file mode 100644
index 44c65ac..0000000
--- a/WallpaperPicker/res/drawable-hdpi/tile_picker_pressed.9.png
+++ /dev/null
Binary files differ
diff --git a/WallpaperPicker/res/drawable-hdpi/tile_picker_selected.9.png b/WallpaperPicker/res/drawable-hdpi/tile_picker_selected.9.png
deleted file mode 100644
index 461bacb..0000000
--- a/WallpaperPicker/res/drawable-hdpi/tile_picker_selected.9.png
+++ /dev/null
Binary files differ
diff --git a/WallpaperPicker/res/drawable-mdpi/tile_picker_focused.9.png b/WallpaperPicker/res/drawable-mdpi/tile_picker_focused.9.png
deleted file mode 100644
index 13b325b..0000000
--- a/WallpaperPicker/res/drawable-mdpi/tile_picker_focused.9.png
+++ /dev/null
Binary files differ
diff --git a/WallpaperPicker/res/drawable-mdpi/tile_picker_pressed.9.png b/WallpaperPicker/res/drawable-mdpi/tile_picker_pressed.9.png
deleted file mode 100644
index 4e8196d..0000000
--- a/WallpaperPicker/res/drawable-mdpi/tile_picker_pressed.9.png
+++ /dev/null
Binary files differ
diff --git a/WallpaperPicker/res/drawable-mdpi/tile_picker_selected.9.png b/WallpaperPicker/res/drawable-mdpi/tile_picker_selected.9.png
deleted file mode 100644
index eee69ec..0000000
--- a/WallpaperPicker/res/drawable-mdpi/tile_picker_selected.9.png
+++ /dev/null
Binary files differ
diff --git a/WallpaperPicker/res/drawable-v21/ic_tick.xml b/WallpaperPicker/res/drawable-v21/ic_tick.xml
new file mode 100644
index 0000000..5b27027
--- /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 0000000..97cdcd6
--- /dev/null
+++ b/WallpaperPicker/res/drawable-v21/wallpaper_tile_fg.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<ripple xmlns:android="http://schemas.android.com/apk/res/android"
+ android:color="#66FFFFFF" >
+
+ <item
+ android:id="@android:id/mask"
+ android:drawable="@android:color/white"/>
+ <item
+ android:bottom="23.25dp"
+ android:left="29.25dp"
+ android:right="29.25dp"
+ android:top="23.25dp">
+ <selector>
+ <item
+ android:drawable="@drawable/ic_tick"
+ android:state_selected="true"/>
+ <item
+ android:drawable="@drawable/ic_tick"
+ android:state_checked="true"/>
+ </selector>
+ </item>
+
+</ripple>
\ No newline at end of file
diff --git a/WallpaperPicker/res/drawable-xhdpi/tile_picker_focused.9.png b/WallpaperPicker/res/drawable-xhdpi/tile_picker_focused.9.png
deleted file mode 100644
index 279e859..0000000
--- a/WallpaperPicker/res/drawable-xhdpi/tile_picker_focused.9.png
+++ /dev/null
Binary files differ
diff --git a/WallpaperPicker/res/drawable-xhdpi/tile_picker_pressed.9.png b/WallpaperPicker/res/drawable-xhdpi/tile_picker_pressed.9.png
deleted file mode 100644
index abe0e00..0000000
--- a/WallpaperPicker/res/drawable-xhdpi/tile_picker_pressed.9.png
+++ /dev/null
Binary files differ
diff --git a/WallpaperPicker/res/drawable-xhdpi/tile_picker_selected.9.png b/WallpaperPicker/res/drawable-xhdpi/tile_picker_selected.9.png
deleted file mode 100644
index b047591..0000000
--- a/WallpaperPicker/res/drawable-xhdpi/tile_picker_selected.9.png
+++ /dev/null
Binary files differ
diff --git a/WallpaperPicker/res/drawable-xxhdpi/tile_picker_focused.9.png b/WallpaperPicker/res/drawable-xxhdpi/tile_picker_focused.9.png
deleted file mode 100644
index 1004c14..0000000
--- a/WallpaperPicker/res/drawable-xxhdpi/tile_picker_focused.9.png
+++ /dev/null
Binary files differ
diff --git a/WallpaperPicker/res/drawable-xxhdpi/tile_picker_pressed.9.png b/WallpaperPicker/res/drawable-xxhdpi/tile_picker_pressed.9.png
deleted file mode 100644
index 9658444..0000000
--- a/WallpaperPicker/res/drawable-xxhdpi/tile_picker_pressed.9.png
+++ /dev/null
Binary files differ
diff --git a/WallpaperPicker/res/drawable-xxhdpi/tile_picker_selected.9.png b/WallpaperPicker/res/drawable-xxhdpi/tile_picker_selected.9.png
deleted file mode 100644
index a3cd303..0000000
--- a/WallpaperPicker/res/drawable-xxhdpi/tile_picker_selected.9.png
+++ /dev/null
Binary files differ
diff --git a/WallpaperPicker/res/drawable/wallpaper_tile_fg.xml b/WallpaperPicker/res/drawable/wallpaper_tile_fg.xml
index c299f32..c66fa50 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 85a989d..136cf01 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 16b11f2..f4008f1 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 2bdf8f1..9f92bc1 100644
--- a/WallpaperPicker/src/com/android/launcher3/SavedWallpaperImages.java
+++ b/WallpaperPicker/src/com/android/launcher3/SavedWallpaperImages.java
@@ -180,7 +180,6 @@
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 @@
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 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 d5c7cd9..fa8ec64 100644
--- a/WallpaperPicker/src/com/android/launcher3/WallpaperCropActivity.java
+++ b/WallpaperPicker/src/com/android/launcher3/WallpaperCropActivity.java
@@ -202,7 +202,7 @@
}
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 0728537..09e0963 100644
--- a/WallpaperPicker/src/com/android/launcher3/WallpaperPickerActivity.java
+++ b/WallpaperPicker/src/com/android/launcher3/WallpaperPickerActivity.java
@@ -86,8 +86,6 @@
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 @@
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 0b28c0e..83a491d 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 7ba2937..8ae1752 100644
--- a/protos/backup.proto
+++ b/protos/backup.proto
@@ -37,12 +37,36 @@
required int64 checksum = 2;
}
+message DeviceProfieData {
+ required float desktop_rows = 1;
+ required float desktop_cols = 2;
+ required float hotseat_count = 3;
+ required int32 allapps_rank = 4;
+}
+
message Journal {
required int32 app_version = 1;
+
+ // Time when the backup was created
required int64 t = 2;
+
+ // Total bytes written during the last backup
+ // OBSOLETE: A state may contain entries which are already present in the backup
+ // and were not written in the last backup
optional int64 bytes = 3;
+
+ // Total entries written during the last backup
+ // OBSOLETE: A state may contain entries which are already present in the backup
+ // and were not written in the last backup
optional int32 rows = 4;
+
+ // Valid keys for this state
repeated Key key = 5;
+
+ // Backup format version.
+ optional int32 backup_version = 6 [default = 1];
+
+ optional DeviceProfieData profile = 7;
}
message Favorite {
diff --git a/res/drawable-hdpi/hand.png b/res/drawable-hdpi/hand.png
deleted file mode 100644
index bd4f6df..0000000
--- a/res/drawable-hdpi/hand.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_home_search_normal_holo.png b/res/drawable-hdpi/ic_home_search_normal_holo.png
deleted file mode 100644
index 3f64d68..0000000
--- a/res/drawable-hdpi/ic_home_search_normal_holo.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_home_voice_search_holo.png b/res/drawable-hdpi/ic_home_voice_search_holo.png
deleted file mode 100644
index dae5446..0000000
--- a/res/drawable-hdpi/ic_home_voice_search_holo.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_pageindicator_current.png b/res/drawable-hdpi/ic_pageindicator_current.png
index 2e841f5..283f44d 100644
--- a/res/drawable-hdpi/ic_pageindicator_current.png
+++ b/res/drawable-hdpi/ic_pageindicator_current.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_pageindicator_default.png b/res/drawable-hdpi/ic_pageindicator_default.png
index 07ab948..47b9989 100644
--- a/res/drawable-hdpi/ic_pageindicator_default.png
+++ b/res/drawable-hdpi/ic_pageindicator_default.png
Binary files differ
diff --git a/res/drawable-hdpi/search_frame.9.png b/res/drawable-hdpi/search_frame.9.png
deleted file mode 100644
index 15ca1f4..0000000
--- a/res/drawable-hdpi/search_frame.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/tab_selected_focused_holo.9.png b/res/drawable-hdpi/tab_selected_focused_holo.9.png
deleted file mode 100644
index 673e3bf..0000000
--- a/res/drawable-hdpi/tab_selected_focused_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/tab_selected_holo.9.png b/res/drawable-hdpi/tab_selected_holo.9.png
deleted file mode 100644
index d57df98..0000000
--- a/res/drawable-hdpi/tab_selected_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/tab_selected_pressed_focused_holo.9.png b/res/drawable-hdpi/tab_selected_pressed_focused_holo.9.png
deleted file mode 100644
index 4b312d9..0000000
--- a/res/drawable-hdpi/tab_selected_pressed_focused_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/tab_selected_pressed_holo.9.png b/res/drawable-hdpi/tab_selected_pressed_holo.9.png
deleted file mode 100644
index 6278eef..0000000
--- a/res/drawable-hdpi/tab_selected_pressed_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/tab_unselected_focused_holo.9.png b/res/drawable-hdpi/tab_unselected_focused_holo.9.png
deleted file mode 100644
index 294991d..0000000
--- a/res/drawable-hdpi/tab_unselected_focused_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/tab_unselected_holo.9.png b/res/drawable-hdpi/tab_unselected_holo.9.png
deleted file mode 100644
index 19532ab..0000000
--- a/res/drawable-hdpi/tab_unselected_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/tab_unselected_pressed_focused_holo.9.png b/res/drawable-hdpi/tab_unselected_pressed_focused_holo.9.png
deleted file mode 100644
index 5140b35..0000000
--- a/res/drawable-hdpi/tab_unselected_pressed_focused_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/tab_unselected_pressed_holo.9.png b/res/drawable-hdpi/tab_unselected_pressed_holo.9.png
deleted file mode 100644
index aadc6f8..0000000
--- a/res/drawable-hdpi/tab_unselected_pressed_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-land-hdpi/ic_home_voice_search_holo.png b/res/drawable-land-hdpi/ic_home_voice_search_holo.png
deleted file mode 100644
index 5a7fc99..0000000
--- a/res/drawable-land-hdpi/ic_home_voice_search_holo.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-land-mdpi/ic_home_voice_search_holo.png b/res/drawable-land-mdpi/ic_home_voice_search_holo.png
deleted file mode 100644
index ee7dde5..0000000
--- a/res/drawable-land-mdpi/ic_home_voice_search_holo.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-land-xhdpi/ic_home_voice_search_holo.png b/res/drawable-land-xhdpi/ic_home_voice_search_holo.png
deleted file mode 100644
index 56bbbbb..0000000
--- a/res/drawable-land-xhdpi/ic_home_voice_search_holo.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-land-xxhdpi/ic_home_voice_search_holo.png b/res/drawable-land-xxhdpi/ic_home_voice_search_holo.png
deleted file mode 100644
index 6ea7368..0000000
--- a/res/drawable-land-xxhdpi/ic_home_voice_search_holo.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/hand.png b/res/drawable-mdpi/hand.png
deleted file mode 100644
index fe5a035..0000000
--- a/res/drawable-mdpi/hand.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_home_search_normal_holo.png b/res/drawable-mdpi/ic_home_search_normal_holo.png
deleted file mode 100644
index 7367c38..0000000
--- a/res/drawable-mdpi/ic_home_search_normal_holo.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_home_voice_search_holo.png b/res/drawable-mdpi/ic_home_voice_search_holo.png
deleted file mode 100644
index f211a7b..0000000
--- a/res/drawable-mdpi/ic_home_voice_search_holo.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_pageindicator_current.png b/res/drawable-mdpi/ic_pageindicator_current.png
index 08f43b4..b41e1bb 100644
--- a/res/drawable-mdpi/ic_pageindicator_current.png
+++ b/res/drawable-mdpi/ic_pageindicator_current.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_pageindicator_default.png b/res/drawable-mdpi/ic_pageindicator_default.png
index 635be4a..e36c25c 100644
--- a/res/drawable-mdpi/ic_pageindicator_default.png
+++ b/res/drawable-mdpi/ic_pageindicator_default.png
Binary files differ
diff --git a/res/drawable-mdpi/search_frame.9.png b/res/drawable-mdpi/search_frame.9.png
deleted file mode 100644
index 058905b..0000000
--- a/res/drawable-mdpi/search_frame.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/tab_selected_focused_holo.9.png b/res/drawable-mdpi/tab_selected_focused_holo.9.png
deleted file mode 100644
index c9972e7..0000000
--- a/res/drawable-mdpi/tab_selected_focused_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/tab_selected_holo.9.png b/res/drawable-mdpi/tab_selected_holo.9.png
deleted file mode 100644
index 587337c..0000000
--- a/res/drawable-mdpi/tab_selected_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/tab_selected_pressed_focused_holo.9.png b/res/drawable-mdpi/tab_selected_pressed_focused_holo.9.png
deleted file mode 100644
index 284f534..0000000
--- a/res/drawable-mdpi/tab_selected_pressed_focused_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/tab_selected_pressed_holo.9.png b/res/drawable-mdpi/tab_selected_pressed_holo.9.png
deleted file mode 100644
index 155c4fc..0000000
--- a/res/drawable-mdpi/tab_selected_pressed_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/tab_unselected_focused_holo.9.png b/res/drawable-mdpi/tab_unselected_focused_holo.9.png
deleted file mode 100644
index f0cecd1..0000000
--- a/res/drawable-mdpi/tab_unselected_focused_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/tab_unselected_holo.9.png b/res/drawable-mdpi/tab_unselected_holo.9.png
deleted file mode 100644
index a2dbf42..0000000
--- a/res/drawable-mdpi/tab_unselected_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/tab_unselected_pressed_focused_holo.9.png b/res/drawable-mdpi/tab_unselected_pressed_focused_holo.9.png
deleted file mode 100644
index f1a2819..0000000
--- a/res/drawable-mdpi/tab_unselected_pressed_focused_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/tab_unselected_pressed_holo.9.png b/res/drawable-mdpi/tab_unselected_pressed_holo.9.png
deleted file mode 100644
index b1223fe..0000000
--- a/res/drawable-mdpi/tab_unselected_pressed_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/hand.png b/res/drawable-xhdpi/hand.png
deleted file mode 100644
index 35b678c..0000000
--- a/res/drawable-xhdpi/hand.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_home_search_normal_holo.png b/res/drawable-xhdpi/ic_home_search_normal_holo.png
deleted file mode 100644
index 0fe1cd1..0000000
--- a/res/drawable-xhdpi/ic_home_search_normal_holo.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_home_voice_search_holo.png b/res/drawable-xhdpi/ic_home_voice_search_holo.png
deleted file mode 100644
index 1fc5cc8..0000000
--- a/res/drawable-xhdpi/ic_home_voice_search_holo.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_pageindicator_current.png b/res/drawable-xhdpi/ic_pageindicator_current.png
index 0e9a52f..8fa774d 100644
--- a/res/drawable-xhdpi/ic_pageindicator_current.png
+++ b/res/drawable-xhdpi/ic_pageindicator_current.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_pageindicator_default.png b/res/drawable-xhdpi/ic_pageindicator_default.png
index d0f14cd..8eb5eb0 100644
--- a/res/drawable-xhdpi/ic_pageindicator_default.png
+++ b/res/drawable-xhdpi/ic_pageindicator_default.png
Binary files differ
diff --git a/res/drawable-xhdpi/search_frame.9.png b/res/drawable-xhdpi/search_frame.9.png
deleted file mode 100644
index 32a0714..0000000
--- a/res/drawable-xhdpi/search_frame.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tab_selected_focused_holo.9.png b/res/drawable-xhdpi/tab_selected_focused_holo.9.png
deleted file mode 100644
index 03cfb09..0000000
--- a/res/drawable-xhdpi/tab_selected_focused_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tab_selected_holo.9.png b/res/drawable-xhdpi/tab_selected_holo.9.png
deleted file mode 100644
index e4229f2..0000000
--- a/res/drawable-xhdpi/tab_selected_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tab_selected_pressed_focused_holo.9.png b/res/drawable-xhdpi/tab_selected_pressed_focused_holo.9.png
deleted file mode 100644
index 2412711..0000000
--- a/res/drawable-xhdpi/tab_selected_pressed_focused_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tab_selected_pressed_holo.9.png b/res/drawable-xhdpi/tab_selected_pressed_holo.9.png
deleted file mode 100644
index e862cb1..0000000
--- a/res/drawable-xhdpi/tab_selected_pressed_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tab_unselected_focused_holo.9.png b/res/drawable-xhdpi/tab_unselected_focused_holo.9.png
deleted file mode 100644
index f3a5cbd..0000000
--- a/res/drawable-xhdpi/tab_unselected_focused_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tab_unselected_holo.9.png b/res/drawable-xhdpi/tab_unselected_holo.9.png
deleted file mode 100644
index 9465173..0000000
--- a/res/drawable-xhdpi/tab_unselected_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tab_unselected_pressed_focused_holo.9.png b/res/drawable-xhdpi/tab_unselected_pressed_focused_holo.9.png
deleted file mode 100644
index 1653600..0000000
--- a/res/drawable-xhdpi/tab_unselected_pressed_focused_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tab_unselected_pressed_holo.9.png b/res/drawable-xhdpi/tab_unselected_pressed_holo.9.png
deleted file mode 100644
index f1eb673..0000000
--- a/res/drawable-xhdpi/tab_unselected_pressed_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/hand.png b/res/drawable-xxhdpi/hand.png
deleted file mode 100644
index 88c2a88..0000000
--- a/res/drawable-xxhdpi/hand.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_home_search_normal_holo.png b/res/drawable-xxhdpi/ic_home_search_normal_holo.png
deleted file mode 100644
index a9523d3..0000000
--- a/res/drawable-xxhdpi/ic_home_search_normal_holo.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_home_voice_search_holo.png b/res/drawable-xxhdpi/ic_home_voice_search_holo.png
deleted file mode 100644
index c9c0b50..0000000
--- a/res/drawable-xxhdpi/ic_home_voice_search_holo.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_pageindicator_current.png b/res/drawable-xxhdpi/ic_pageindicator_current.png
index b74e92e..22b290e 100644
--- a/res/drawable-xxhdpi/ic_pageindicator_current.png
+++ b/res/drawable-xxhdpi/ic_pageindicator_current.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_pageindicator_default.png b/res/drawable-xxhdpi/ic_pageindicator_default.png
index e362ece..e608cae 100644
--- a/res/drawable-xxhdpi/ic_pageindicator_default.png
+++ b/res/drawable-xxhdpi/ic_pageindicator_default.png
Binary files differ
diff --git a/res/drawable-xxhdpi/search_bg_panel.9.png b/res/drawable-xxhdpi/search_bg_panel.9.png
deleted file mode 100644
index 85cae17..0000000
--- a/res/drawable-xxhdpi/search_bg_panel.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/search_frame.9.png b/res/drawable-xxhdpi/search_frame.9.png
deleted file mode 100644
index f297bf1..0000000
--- a/res/drawable-xxhdpi/search_frame.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/tab_selected_focused_holo.9.png b/res/drawable-xxhdpi/tab_selected_focused_holo.9.png
deleted file mode 100644
index 2400c65..0000000
--- a/res/drawable-xxhdpi/tab_selected_focused_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/tab_selected_holo.9.png b/res/drawable-xxhdpi/tab_selected_holo.9.png
deleted file mode 100644
index 5067cbb..0000000
--- a/res/drawable-xxhdpi/tab_selected_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/tab_selected_pressed_holo.9.png b/res/drawable-xxhdpi/tab_selected_pressed_holo.9.png
deleted file mode 100644
index 84c246d..0000000
--- a/res/drawable-xxhdpi/tab_selected_pressed_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/tab_unselected_focused_holo.9.png b/res/drawable-xxhdpi/tab_unselected_focused_holo.9.png
deleted file mode 100644
index 939e0c3..0000000
--- a/res/drawable-xxhdpi/tab_unselected_focused_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/tab_unselected_holo.9.png b/res/drawable-xxhdpi/tab_unselected_holo.9.png
deleted file mode 100644
index 62ca6cf..0000000
--- a/res/drawable-xxhdpi/tab_unselected_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/tab_unselected_pressed_holo.9.png b/res/drawable-xxhdpi/tab_unselected_pressed_holo.9.png
deleted file mode 100644
index 58ac0d6..0000000
--- a/res/drawable-xxhdpi/tab_unselected_pressed_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable/tab_widget_indicator_selector.xml b/res/drawable/tab_widget_indicator_selector.xml
deleted file mode 100644
index d06f757..0000000
--- 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 8cd8673..6f95bd5 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 93bbc07..9672dd8 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 307cba8..db93da8 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 d56e380..0000000
--- 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 9e98d42..af30a32 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 8e35f5c..c0b5267 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 dde8dbc..81689d3 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 4c9963d..0000000
--- 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 b42d697..c4573d5 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/external_widget_drop_list_item.xml b/res/layout-sw720dp/external_widget_drop_list_item.xml
deleted file mode 100644
index 48e333b..0000000
--- a/res/layout-sw720dp/external_widget_drop_list_item.xml
+++ /dev/null
@@ -1,39 +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.
--->
-
-<LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
-
- 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_width="match_parent"
- android:layout_height="match_parent"
- android:layout_marginStart="5dp"
- android:gravity="center_vertical"
- android:textSize="18sp" />
-</LinearLayout>
diff --git a/res/layout-sw720dp/launcher.xml b/res/layout-sw720dp/launcher.xml
index 6261541..960ccf3 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 7eaeafa..0000000
--- 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 4c9963d..0000000
--- 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 bf5f71b..e42576f 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 e299b32..a8344e3 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 f38a500..0000000
--- 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 dc9ed2a..7bef889 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
similarity index 78%
rename from res/layout/tab_widget_indicator.xml
rename to res/layout/launcher_overlay.xml
index de7c50e..b35a2d8 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/launcher_overlay_example.xml b/res/layout/launcher_overlay_example.xml
new file mode 100644
index 0000000..7d92d4f
--- /dev/null
+++ b/res/layout/launcher_overlay_example.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<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="match_parent"
+ launcher:layout_ignoreInsets="true">
+
+ <FrameLayout
+ android:id="@+id/search_overlay"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ 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 41e6ec7..0000000
--- 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 558900c..4b7423e 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:textAllCaps="true"
- android:textSize="12sp"/>
- <TextView
- android:id="@+id/settings_button"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="end|top"
- android:text="@string/settings_button_text"
- android:drawablePadding="4dp"
android:gravity="center_horizontal"
- android:drawableTop="@drawable/setting_button"
- android:fontFamily="sans-serif-condensed"
+ android:text="@string/widget_button_text"
android:textAllCaps="true"
android:textSize="12sp" />
-</FrameLayout>
+
+ <TextView
+ android:id="@+id/settings_button"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:drawablePadding="4dp"
+ 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" />
+
+</LinearLayout>
\ No newline at end of file
diff --git a/res/layout/page_indicator.xml b/res/layout/page_indicator.xml
index 14eff75..68fe3dd 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 7c0c389..686d275 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 2d51b93..af2d0163 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" >
- <include
- layout="@layout/drop_target_bar" />
+ <FrameLayout
+ style="@style/DropTargetButtonContainer"
+ android:layout_weight="1" >
+
+ <!-- Delete target -->
+
+ <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 4e5303a..ed8d43e 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 855cf39..83b319b 100644
--- a/res/layout/workspace_screen.xml
+++ b/res/layout/workspace_screen.xml
@@ -16,7 +16,7 @@
<com.android.launcher3.CellLayout
xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3"
+ xmlns:launcher="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
diff --git a/res/mipmap-hdpi/ic_launcher_application.png b/res/mipmap-hdpi/ic_launcher_application.png
deleted file mode 100644
index b9aa101..0000000
--- a/res/mipmap-hdpi/ic_launcher_application.png
+++ /dev/null
Binary files differ
diff --git a/res/mipmap-mdpi/ic_launcher_application.png b/res/mipmap-mdpi/ic_launcher_application.png
deleted file mode 100644
index 4771b85..0000000
--- a/res/mipmap-mdpi/ic_launcher_application.png
+++ /dev/null
Binary files differ
diff --git a/res/mipmap-xhdpi/ic_launcher_application.png b/res/mipmap-xhdpi/ic_launcher_application.png
deleted file mode 100644
index 932f0f7..0000000
--- a/res/mipmap-xhdpi/ic_launcher_application.png
+++ /dev/null
Binary files differ
diff --git a/res/mipmap-xxhdpi/ic_launcher_application.png b/res/mipmap-xxhdpi/ic_launcher_application.png
deleted file mode 100644
index 7fc739a..0000000
--- a/res/mipmap-xxhdpi/ic_launcher_application.png
+++ /dev/null
Binary files differ
diff --git a/res/values-af-land/strings.xml b/res/values-af-land/strings.xml
deleted file mode 100644
index b976926..0000000
--- 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 4a4bb78..f37f08f 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 b976926..0000000
--- 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 d77744c..1a25f66 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 b976926..0000000
--- 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 8b6aa02..592be58 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 b976926..0000000
--- 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 dcd1930..3f710db 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 f60f1c5..1434201 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 b976926..0000000
--- 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 6d10235..89e582a 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 b976926..0000000
--- 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 f729a46..69ec22c 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 b976926..0000000
--- 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 85159b2..5fa6aa6 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 b976926..0000000
--- 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 698a254..059983e 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 b976926..0000000
--- 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 3eec27d..12f0dfe 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 b976926..0000000
--- 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 615e5c9..0d004fe 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 615e5c9..0d004fe 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 b976926..0000000
--- 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 b976926..0000000
--- 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 31afa3e..4408080 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 4e91412..898d0ea 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 fa352a1..76b20ab 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 4a4c959..e02479c 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 b976926..0000000
--- 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 13f40e2..924cccf 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 b976926..0000000
--- 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 3990a16..a5da03f 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 b976926..0000000
--- 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 f428350..62a2b89 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 31448f1..d23b6a4 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 c053b07..96a53dc 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 9058b78..9372489 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 b976926..0000000
--- 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 c881077..702b474 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 b976926..0000000
--- 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 08d3095..513548a 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 4ec39c8..940c14b 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 b976926..0000000
--- 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 137e3cc..b0c5d13 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 71f0ede..a3fa0bc 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 b976926..0000000
--- 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 b01b251..d78d032 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 b976926..0000000
--- 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 6318207..61fb53e 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 b976926..0000000
--- 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 232845a..ec872b8 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 2fb51f5..b96d3d2 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 288129a..c5b5a62 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 bcd6060..3a1c82d 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 e84ece0..7a07051 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 b976926..0000000
--- 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 41c854e..c73b431 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 5b50555..a8a605b 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 ec4c7e7..0000000
--- 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 87a7444..8a255c9 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 1d953ff..65f01b7 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 b976926..0000000
--- 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 f7db792..897c2fd 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 b976926..0000000
--- 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 75eb054..13a4760 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 0d77571..dcc55d7 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 32329f1..cf5efaa 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 34fb794..f258b4c 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 2e51e7b..098e830 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 b976926..0000000
--- 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 3c58762..532b6ad 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 8048b02..6688035 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 b976926..0000000
--- 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 ff8280e..a9bbe08 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 fe75ea7..815873d 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 b976926..0000000
--- 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 470eb87..8a32fd1 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 b976926..0000000
--- 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 61a51e0..4eabae9 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 ab6a1eb..0000000
--- 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 b976926..0000000
--- 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 b976926..0000000
--- 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 2fe062a..4397ebf 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 20b193a..07c8214 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 b976926..0000000
--- 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 b976926..0000000
--- 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 04aebc8..54cb46c 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 b976926..0000000
--- 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 b1d7713..70ef0f5 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 d334da9..ab3abb8 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 b976926..0000000
--- 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 a003679..3f41f2d 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 b976926..0000000
--- 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 9c5bebd..d5a34d5 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 b976926..0000000
--- 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 421f8d3..9f40890 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 b976926..0000000
--- 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 e149c9e..25f4d26 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 b976926..0000000
--- 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 07d0913..fa81061 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 24f4ba2..8ac3b5e 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 69d6e58..c9f2981 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 57f07ac..0000000
--- 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 71f0304..cbc1e29 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 f3aef1c..9dba6f6 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 b48d6b8..bfbc792 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 b976926..0000000
--- 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 beed898..0fc20d2 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 b976926..0000000
--- 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 7c6acd2..4d2f1d4 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 b976926..0000000
--- 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 6c0bb69..6c78f6f 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 b976926..0000000
--- 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 52f3761..71e1816 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 33b502e..ba1d3fa 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 791f6c8..a3c5670 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 71c4bfa..11d2a1f 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 b976926..0000000
--- 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 4891230..5bc1627 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 b976926..0000000
--- 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 3365581..b7c42fe 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 e1c2063..2eb7008 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 b976926..0000000
--- 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 2d40059..52e7583 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 b976926..0000000
--- 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 89cd5cc..aea09e8 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 65f8f22..3331cde 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 29837ea..2daf9fe 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 2c9e689..f12cb57 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 ff3509b..b6f4237 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 @@
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 56a205f..77798f1 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 7e1301c..0000000
--- 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 f54a204..0000000
--- 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 f54a204..0000000
--- 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 90a7865..0000000
--- 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 38d2fa5..72c6693 100644
--- a/src/com/android/launcher3/AllAppsList.java
+++ b/src/com/android/launcher3/AllAppsList.java
@@ -18,10 +18,6 @@
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 @@
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 @@
data.remove(i);
}
}
- mIconCache.remove(packageName, user);
+ if (clearCache) {
+ mIconCache.remove(packageName, user);
+ }
}
/**
@@ -149,9 +145,7 @@
// 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 bfcad84..a66bac0 100644
--- a/src/com/android/launcher3/AppInfo.java
+++ b/src/com/android/launcher3/AppInfo.java
@@ -84,16 +84,11 @@
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 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 1bd2907..c8187f0 100644
--- a/src/com/android/launcher3/AppsCustomizePagedView.java
+++ b/src/com/android/launcher3/AppsCustomizePagedView.java
@@ -366,11 +366,7 @@
// 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 @@
!(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 @@
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 9a516fd..a271712 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 @@
mPagedView.reset();
}
+ void trimMemory() {
+ mPagedView.trimMemory();
+ }
+
public void onWindowVisible() {
if (getVisibility() == VISIBLE) {
mContent.setVisibility(VISIBLE);
@@ -141,14 +131,6 @@
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 00f0cf3..a5d2228 100644
--- a/src/com/android/launcher3/AutoInstallsLayout.java
+++ b/src/com/android/launcher3/AutoInstallsLayout.java
@@ -36,7 +36,6 @@
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.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 @@
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 @@
private final AppWidgetHost mAppWidgetHost;
private final LayoutParserCallback mCallback;
- private final PackageManager mPackageManager;
+ protected final PackageManager mPackageManager;
+ protected final Resources mSourceRes;
+ protected final int mLayoutId;
+
+ private final int mHotseatAllAppsRank;
+
+ private final long[] mTemp = new long[2];
private final ContentValues mValues;
+ private final String mRootTag;
- private final Resources mRes;
- private final int mLayoutId;
-
- 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,47 +173,62 @@
if (type != XmlPullParser.START_TAG) {
continue;
}
-
- 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);
-
- 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++;
- }
+ count += parseAndAddNode(parser, tagParserMap, screenIds);
}
return count;
}
+ /**
+ * 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));
+ }
+ }
+
+ /**
+ * 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 0;
+ }
+
protected long addShortcut(String title, Intent intent, int type) {
long id = mCallback.generateNewItemId();
mValues.put(Favorites.INTENT, intent.toUri(0));
@@ -225,7 +248,7 @@
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 @@
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 @@
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 @@
}
}
- 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 @@
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 @@
}
}
- 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 @@
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 @@
}
}
- 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 @@
* 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 @@
* 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 a368796..07f3045 100644
--- a/src/com/android/launcher3/BubbleTextView.java
+++ b/src/com/android/launcher3/BubbleTextView.java
@@ -40,7 +40,7 @@
*/
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 @@
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 0000000..e3ea40e
--- /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 05e8906..ea058ea 100644
--- a/src/com/android/launcher3/DeleteDropTarget.java
+++ b/src/com/android/launcher3/DeleteDropTarget.java
@@ -21,8 +21,6 @@
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.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 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 daf5556..d6aadce 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -33,6 +33,7 @@
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 @@
private float hotseatIconSize;
int defaultLayoutId;
- int defaultNoAllAppsLayoutId;
boolean isLandscape;
boolean isTablet;
@@ -122,9 +122,7 @@
int allAppsNumRows;
int allAppsNumCols;
int searchBarSpaceWidthPx;
- int searchBarSpaceMaxWidthPx;
int searchBarSpaceHeightPx;
- int searchBarHeightPx;
int pageIndicatorHeightPx;
int allAppsButtonVisualSize;
@@ -136,7 +134,7 @@
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 @@
numHotseatIcons = hs;
hotseatIconSize = his;
defaultLayoutId = dlId;
- defaultNoAllAppsLayoutId = dnalId;
}
DeviceProfile() {
@@ -215,9 +212,6 @@
// 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 6d0a2be..480dce9 100644
--- a/src/com/android/launcher3/DragController.java
+++ b/src/com/android/launcher3/DragController.java
@@ -26,10 +26,16 @@
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 @@
}
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 a8a61ea..a352b79 100644
--- a/src/com/android/launcher3/DragLayer.java
+++ b/src/com/android/launcher3/DragLayer.java
@@ -38,12 +38,14 @@
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 @@
private TouchCompleteListener mTouchCompleteListener;
- private final Rect mInsets = new Rect();
-
private View mOverlayView;
private int mTopViewIndex;
private int mChildCountOnLastUpdate = -1;
@@ -89,6 +89,8 @@
private Drawable mLeftHoverDrawableActive;
private Drawable mRightHoverDrawableActive;
+ private boolean mBlockTouches = false;
+
/**
* Used to create a new DragLayer from XML.
*
@@ -101,7 +103,6 @@
// 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
@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 c83659a..0000000
--- 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 94a07d7..aa08148 100644
--- a/src/com/android/launcher3/DynamicGrid.java
+++ b/src/com/android/launcher3/DynamicGrid.java
@@ -60,41 +60,30 @@
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 f4c49d7..095c563 100644
--- a/src/com/android/launcher3/FirstFrameAnimatorHelper.java
+++ b/src/com/android/launcher3/FirstFrameAnimatorHelper.java
@@ -92,12 +92,14 @@
}
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 d529b39..e607047 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 @@
}
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 @@
}
/**
- * 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 @@
}
/**
- * 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 12b7a40..7d4664a 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 @@
// 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 @@
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 @@
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 @@
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 18ac092..0000000
--- 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 5344a7e..0000000
--- 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 7ef0355..0000000
--- 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 bb71d77..5a0875b 100644
--- a/src/com/android/launcher3/IconCache.java
+++ b/src/com/android/launcher3/IconCache.java
@@ -24,12 +24,10 @@
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 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 @@
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 @@
/**
* 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 @@
/**
* 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 @@
/**
* 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);
+ CacheEntry entry = cacheLocked(application.componentName, info, labelCache,
+ info.getUser(), false);
- application.title = entry.title;
- application.iconBitmap = entry.icon;
- application.contentDescription = entry.contentDescription;
- }
+ application.title = entry.title;
+ application.iconBitmap = entry.icon;
+ application.contentDescription = entry.contentDescription;
}
- public Bitmap getIcon(Intent intent, UserHandleCompat user) {
- return getIcon(intent, null, user, true);
- }
-
- 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 @@
* 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 @@
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 @@
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 @@
* 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 (!user.equals(UserHandleCompat.myUserHandle()) || componentName == null) {
+ return;
}
- if (componentName == null) {
- return false;
- }
- if (mCache.remove(componentName) != null) {
- if (DEBUG) Log.d(TAG, "removed pre-loaded icon from the in-memory cache");
- }
+ 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 @@
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 0000000..7343bf6
--- /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 2edde4f..1ab3085 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.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 @@
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));
+ 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);
}
- 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);
- }
- 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 @@
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 @@
}
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 @@
// 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 @@
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 @@
}
}
+ 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 @@
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 @@
}
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 74b9e3d..0000000
--- 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 42ec4fb..ac46fd3 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -50,10 +50,10 @@
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.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.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.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 @@
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 @@
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 @@
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 @@
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 @@
// 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 @@
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 @@
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 @@
.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 @@
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 @@
}
}
- @Override
- public void onLauncherProviderChange() { }
+ private LauncherCallbacks mLauncherCallbacks;
- /** To be overriden by subclasses to hint to Launcher that we have custom content */
+ 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() {
+ if (mLauncherCallbacks != null) {
+ mLauncherCallbacks.onLauncherProviderChange();
+ }
+ }
+
+ /** 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 @@
* {@link #hasCustomContentToLeft()} is {@code true}.
*/
protected void populateCustomContentContainer() {
+ if (mLauncherCallbacks != null) {
+ mLauncherCallbacks.populateCustomContentContainer();
+ }
}
/**
@@ -540,28 +549,6 @@
}
}
- 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 @@
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 @@
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 @@
// 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 @@
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 @@
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 @@
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 @@
startTime = System.currentTimeMillis();
Log.v(TAG, "Launcher.onResume()");
}
+
+ if (mLauncherCallbacks != null) {
+ mLauncherCallbacks.preOnResume();
+ }
+
super.onResume();
// Restore the previous launcher state
@@ -1037,12 +1047,6 @@
// 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 @@
mWorkspace.onResume();
PackageInstallerCompat.getInstance(this).onResume();
+
+ if (mLauncherCallbacks != null) {
+ mLauncherCallbacks.onResume();
+ }
}
@Override
@@ -1077,25 +1085,10 @@
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 @@
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 void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
mHasFocus = hasFocus;
+
+ if (mLauncherCallbacks != null) {
+ mLauncherCallbacks.onWindowFocusChanged(hasFocus);
+ }
}
private boolean acceptFilter() {
@@ -1335,9 +1409,6 @@
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 @@
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 @@
boolean foundCellSpan = false;
- ShortcutInfo info = mModel.infoFromShortcutIntent(this, data, null);
+ ShortcutInfo info = mModel.infoFromShortcutIntent(this, data);
if (info == null) {
return;
}
@@ -1887,8 +1959,11 @@
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 @@
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 @@
outState.putInt("apps_customize_currentIndex", currentIndex);
}
outState.putSerializable(RUNTIME_STATE_VIEW_IDS, mItemIdToViewId);
+
+ if (mLauncherCallbacks != null) {
+ mLauncherCallbacks.onSaveInstanceState(outState);
+ }
}
@Override
@@ -2034,8 +2104,11 @@
mWorkspace = null;
mDragController = null;
- PackageInstallerCompat.getInstance(this).onStop();
LauncherAnimUtils.onDestroyActivity();
+
+ if (mLauncherCallbacks != null) {
+ mLauncherCallbacks.onDestroy();
+ }
}
public DragController getDragController() {
@@ -2089,6 +2162,11 @@
*/
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 @@
} 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 @@
showWorkspace(true);
}
}
+ if (mLauncherCallbacks != null) {
+ return mLauncherCallbacks.onPrepareOptionsMenu(menu);
+ }
+
return false;
}
@@ -2187,7 +2269,11 @@
}
}
- protected void onWorkspaceLockedChanged() { }
+ protected void onWorkspaceLockedChanged() {
+ if (mLauncherCallbacks != null) {
+ mLauncherCallbacks.onWorkspaceLockedChanged();
+ }
+ }
private void resetAddInfo() {
mPendingAddInfo.container = ItemInfo.NO_ID;
@@ -2349,6 +2435,9 @@
}
protected ComponentName getWallpaperPickerComponent() {
+ if (mLauncherCallbacks != null) {
+ return mLauncherCallbacks.getWallpaperPickerComponent();
+ }
return new ComponentName(getPackageName(), LauncherWallpaperPickerActivity.class.getName());
}
@@ -2369,7 +2458,7 @@
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 @@
@Override
public void onBackPressed() {
+ if (mLauncherCallbacks != null && mLauncherCallbacks.handleBackPressed()) {
+ return;
+ }
+
if (isAllAppsVisible()) {
if (mAppsCustomizeContent.getContentType() ==
AppsCustomizePagedView.ContentType.Applications) {
@@ -2469,6 +2562,9 @@
public void onClickPagedViewIcon(View v) {
startAppShortcutOrInfoActivity(v);
+ if (mLauncherCallbacks != null) {
+ mLauncherCallbacks.onClickPagedViewIcon(v);
+ }
}
public boolean onTouch(View v, MotionEvent event) {
@@ -2479,6 +2575,11 @@
* 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 @@
}
/**
- * 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 @@
} 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 @@
// 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 @@
// Start activities
startAppShortcutOrInfoActivity(v);
+
+ if (mLauncherCallbacks != null) {
+ mLauncherCallbacks.onClickAppShortcut(v);
+ }
}
private void startAppShortcutOrInfoActivity(View v) {
@@ -2697,6 +2775,10 @@
}
}
}
+
+ if (mLauncherCallbacks != null) {
+ mLauncherCallbacks.onClickFolderIcon(v);
+ }
}
/**
@@ -2705,7 +2787,14 @@
*/
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 @@
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 @@
*/
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 @@
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 @@
* 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 @@
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 @@
if (mSearchDropTargetBar != null) {
mSearchDropTargetBar.hideSearchBar(false);
}
+
+ // This can hold unnecessary references to views.
+ mStateAnimation = null;
}
});
@@ -3399,11 +3512,7 @@
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 @@
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 @@
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 @@
content.setCurrentPage(content.getNextPage());
mAppsCustomizeContent.updateCurrentPageScroll();
+
+ // This can hold unnecessary references to views.
+ mStateAnimation = null;
}
});
@@ -3676,11 +3788,7 @@
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 @@
@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,260 +3946,64 @@
// 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 (mLauncherCallbacks != null && mLauncherCallbacks.providesSearch()) {
+ return mLauncherCallbacks.getQsbBar();
+ }
+
if (mQsb == null) {
- mQsb = mInflater.inflate(R.layout.qsb, mSearchDropTargetBar, false);
- mSearchDropTargetBar.addView(mQsb);
+ AppWidgetProviderInfo searchProvider = Utilities.getSearchWidgetProvider(this);
+ if (searchProvider == null) {
+ return null;
+ }
+
+ 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;
+ }
+
+ // Try to bind a new widget
+ widgetId = mAppWidgetHost.allocateAppWidgetId();
+
+ if (!AppWidgetManagerCompat.getInstance(this)
+ .bindAppWidgetIdIfAllowed(widgetId, searchProvider, opts)) {
+ mAppWidgetHost.deleteAppWidgetId(widgetId);
+ widgetId = -1;
+ }
+
+ sp.edit()
+ .putInt(QSB_WIDGET_ID, widgetId)
+ .putString(QSB_WIDGET_PROVIDER, searchProvider.provider.flattenToString())
+ .commit();
+ }
+
+ if (widgetId != -1) {
+ mQsb = mAppWidgetHost.createView(this, widgetId, searchProvider);
+ mQsb.updateAppWidgetOptions(opts);
+ mQsb.setPadding(0, 0, 0, 0);
+ mSearchDropTargetBar.addView(mQsb);
+ }
}
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 (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);
- }
-
- protected boolean updateVoiceSearchIcon(boolean searchVisible) {
- final View voiceButtonContainer = findViewById(R.id.voice_button_container);
- final View voiceButton = findViewById(R.id.voice_button);
-
- // 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();
-
- 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);
- }
- 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();
- }
- }
-
- /**
- * 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);
- }
-
@Override
public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
final boolean result = super.dispatchPopulateAccessibilityEvent(event);
@@ -4455,8 +4374,9 @@
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 @@
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 @@
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 @@
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 @@
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 @@
LauncherModel.getSortedWidgetsAndShortcuts(this));
}
}
+ if (mLauncherCallbacks != null) {
+ mLauncherCallbacks.bindAllApplications(apps);
+ }
}
/**
@@ -4709,31 +4638,54 @@
return;
}
- if (mWorkspace != null) {
- mWorkspace.updateShortcutsAndWidgets(apps);
- }
-
if (!LauncherAppState.isDisableAllApps() &&
mAppsCustomizeContent != null) {
mAppsCustomizeContent.updateApps(apps);
}
}
- /**
- * Packages were restored
- */
- public void bindAppsRestored(final ArrayList<AppInfo> apps) {
+ @Override
+ public void bindWidgetsRestored(final ArrayList<LauncherAppWidgetInfo> widgets) {
Runnable r = new Runnable() {
public void run() {
- bindAppsRestored(apps);
+ bindWidgetsRestored(widgets);
+ }
+ };
+ if (waitUntilResume(r)) {
+ return;
+ }
+ mWorkspace.widgetsRestored(widgets);
+ }
+
+ /**
+ * Some shortcuts were updated in the background.
+ *
+ * Implementation of the method from LauncherModel.Callbacks.
+ */
+ @Override
+ public void bindShortcutsChanged(final ArrayList<ShortcutInfo> updated,
+ final ArrayList<ShortcutInfo> removed, final UserHandleCompat user) {
+ Runnable r = new Runnable() {
+ public void run() {
+ 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 @@
* 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 @@
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 @@
}
}
- /**
- * 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 @@
* 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 @@
* 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 @@
* screen that must be displayed and dismissed.
*/
protected boolean hasDismissableIntroScreen() {
+ if (mLauncherCallbacks != null) {
+ return mLauncherCallbacks.hasDismissableIntroScreen();
+ }
return false;
}
@@ -4989,6 +4927,9 @@
* 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 @@
if (introScreen != null) {
mDragLayer.showOverlayView(introScreen);
}
+ if (mLauncherOverlayContainer != null) {
+ mLauncherOverlayContainer.setVisibility(View.INVISIBLE);
+ }
}
public void dismissIntroScreen() {
@@ -5018,11 +4962,17 @@
@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 @@
@Override
public void onPageSwitch(View newPage, int newPageIndex) {
+ if (mLauncherCallbacks != null) {
+ mLauncherCallbacks.onPageSwitch(newPage, newPageIndex);
+ }
}
/**
@@ -5131,6 +5084,9 @@
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 246278f..b7c45a3 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.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 @@
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 @@
};
LauncherModel setLauncher(Launcher launcher) {
- if (mModel == null) {
- throw new IllegalStateException("setLauncher() called before init()");
- }
mModel.initialize(launcher);
return mModel;
}
@@ -186,26 +190,48 @@
}
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 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 c20c693..3868a57 100644
--- a/src/com/android/launcher3/LauncherBackupAgentHelper.java
+++ b/src/com/android/launcher3/LauncherBackupAgentHelper.java
@@ -22,7 +22,6 @@
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 @@
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 @@
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();
- if (!hasData) {
+ 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 && 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 201f3e9..4374347 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.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.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.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 @@
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 boolean mRestoreEnabled;
-
- private HashMap<ComponentName, AppWidgetProviderInfo> mWidgetMap;
-
+ private final HashSet<String> mExistingKeys;
private final ArrayList<Key> mKeys;
- public LauncherBackupHelper(Context context, boolean restoreEnabled) {
+ private IconCache mIconCache;
+ private BackupManager mBackupManager;
+ private HashMap<ComponentName, AppWidgetProviderInfo> mWidgetMap;
+ private byte[] mBuffer = new byte[512];
+ private long mLastBackupRestoreTime;
+
+ private DeviceProfieData mCurrentProfile;
+ boolean restoreSuccessful;
+
+ 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);
}
- sBackupManager.dataChanged();
+ 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));
+ }
+ }
}
/**
@@ -173,7 +183,6 @@
* @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 @@
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);
- 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 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));
}
- out.key = keys.toArray(new BackupProtos.Key[keys.size()]);
- } else {
- out = in;
+ mExistingKeys.removeAll(validKeys);
+
+ // Delete anything left in the existing keys.
+ for (String deleted: mExistingKeys) {
+ if (VERBOSE) Log.v(TAG, "dropping deleted item " + deleted);
+ data.writeEntityHeader(deleted, -1);
+ }
+
+ 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 @@
*/
@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 @@
* @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 @@
* @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 @@
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 @@
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 @@
} 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 @@
* @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 @@
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 @@
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 @@
} 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 @@
* @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 @@
}
/** 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 @@
}
/** 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 @@
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 @@
}
}
- 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 @@
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 @@
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 @@
}
/** 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 @@
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 @@
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 @@
// 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 @@
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 @@
}
/** 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 @@
}
- // 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 @@
.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 0000000..a1f4e0b
--- /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 458d81f..ef8e8ab 100644
--- a/src/com/android/launcher3/LauncherClings.java
+++ b/src/com/android/launcher3/LauncherClings.java
@@ -27,7 +27,6 @@
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 @@
/** 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 0000000..b264042
--- /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 0000000..fa05365
--- /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 c64506d..954887d 100644
--- a/src/com/android/launcher3/LauncherModel.java
+++ b/src/com/android/launcher3/LauncherModel.java
@@ -30,6 +30,7 @@
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.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 @@
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 @@
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 @@
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 @@
// 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 @@
// 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 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 @@
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 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 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 @@
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 @@
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 @@
}
callbacks.bindAppsAdded(addedWorkspaceScreensFinal,
addNotAnimated, addAnimated, null);
- if (!restoredAppsFinal.isEmpty()) {
- callbacks.bindAppsUpdated(restoredAppsFinal);
- }
}
}
});
@@ -870,7 +850,8 @@
* 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 @@
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 @@
* @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 @@
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 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 @@
}
// 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 @@
// 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
// 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 @@
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 @@
// 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 @@
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 @@
// 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 @@
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 @@
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 @@
}
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 @@
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 @@
} 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 @@
});
}
+ // 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 @@
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 @@
// 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 @@
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 @@
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 @@
}
}
- 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 @@
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 @@
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 @@
// 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 @@
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 6f9c05c..0000000
--- 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 6cc1688..1715b02 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.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.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.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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
}
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 @@
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 @@
}
// 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 @@
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 @@
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 @@
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 @@
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 @@
// 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 @@
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 @@
}
}
}
-
- 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 0000000..e8c11c4
--- /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 48fc0c9..7d65f46 100644
--- a/src/com/android/launcher3/PagedView.java
+++ b/src/com/android/launcher3/PagedView.java
@@ -204,6 +204,8 @@
protected boolean mAllowLongPress = true;
+ private boolean mWasInOverscroll = false;
+
// Page Indicator
private int mPageIndicatorViewId;
private PageIndicator mPageIndicator;
@@ -625,6 +627,7 @@
// a method that subclasses can override to add behavior
protected void onPageEndMoving() {
+ mWasInOverscroll = false;
}
/**
@@ -663,6 +666,7 @@
if (isXBeforeFirstPage) {
super.scrollTo(0, y);
if (mAllowOverScroll) {
+ mWasInOverscroll = true;
if (isRtl) {
overScroll(x - mMaxScrollX);
} else {
@@ -672,6 +676,7 @@
} else if (isXAfterLastPage) {
super.scrollTo(mMaxScrollX, y);
if (mAllowOverScroll) {
+ mWasInOverscroll = true;
if (isRtl) {
overScroll(x);
} else {
@@ -679,6 +684,10 @@
}
}
} else {
+ if (mWasInOverscroll) {
+ overScroll(0);
+ mWasInOverscroll = false;
+ }
mOverScrollX = x;
super.scrollTo(x, y);
}
@@ -1513,6 +1522,7 @@
mLastMotionXRemainder = 0;
mTouchX = getViewportOffsetX() + getScrollX();
mSmoothingTime = System.nanoTime() / NANOTIME_DIV;
+ onScrollInteractionBegin();
pageBeginMoving();
}
}
@@ -1752,6 +1762,7 @@
mActivePointerId = ev.getPointerId(0);
if (mTouchState == TOUCH_STATE_SCROLLING) {
+ onScrollInteractionBegin();
pageBeginMoving();
}
break;
@@ -1940,6 +1951,7 @@
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 @@
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 71f5eea..7d82795 100644
--- a/src/com/android/launcher3/PagedViewWidgetImageView.java
+++ b/src/com/android/launcher3/PagedViewWidgetImageView.java
@@ -21,7 +21,7 @@
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 2a29c33..0e59369 100644
--- a/src/com/android/launcher3/PagedViewWithDraggableItems.java
+++ b/src/com/android/launcher3/PagedViewWithDraggableItems.java
@@ -91,6 +91,10 @@
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 d23a330..179c60a 100644
--- a/src/com/android/launcher3/PendingAppWidgetHostView.java
+++ b/src/com/android/launcher3/PendingAppWidgetHostView.java
@@ -41,9 +41,9 @@
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 @@
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 @@
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 @@
}
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 @@
@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 @@
@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 435dbda..99c2e08 100644
--- a/src/com/android/launcher3/SearchDropTargetBar.java
+++ b/src/com/android/launcher3/SearchDropTargetBar.java
@@ -19,9 +19,9 @@
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 @@
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 @@
private int mBarHeight;
private boolean mDeferOnDragEnd = false;
- private Drawable mPreviousBackground;
private boolean mEnableDropDownDropTargets;
public SearchDropTargetBar(Context context, AttributeSet attrs) {
@@ -69,29 +68,42 @@
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 @@
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 @@
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 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 daf3434..01f7931 100644
--- a/src/com/android/launcher3/ShortcutInfo.java
+++ b/src/com/android/launcher3/ShortcutInfo.java
@@ -88,10 +88,20 @@
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 f3977e4..a879865 100644
--- a/src/com/android/launcher3/Stats.java
+++ b/src/com/android/launcher3/Stats.java
@@ -38,12 +38,10 @@
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 @@
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 @@
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 @@
}
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 @@
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 80d4b22..215d63d 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 @@
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 @@
* 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 @@
* 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
- return icon;
- } else {
- // Icon is too small, render to a larger bitmap
- final Resources resources = context.getResources();
- return createIconBitmap(new BitmapDrawable(resources, icon), context);
+ synchronized (sCanvas) { // we share the statics :-(
+ if (sIconWidth == -1) {
+ initStatics(context);
+ }
}
+ if (sIconWidth == icon.getWidth() && sIconHeight == icon.getHeight()) {
+ return icon;
+ }
+ return createIconBitmap(new BitmapDrawable(context.getResources(), icon), context);
}
/**
@@ -172,8 +184,8 @@
}
// 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 @@
}
/**
- * 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 @@
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 @@
}
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 5aa7190..4e6fe1f 100644
--- a/src/com/android/launcher3/WidgetPreviewLoader.java
+++ b/src/com/android/launcher3/WidgetPreviewLoader.java
@@ -12,6 +12,7 @@
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.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 @@
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 @@
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 @@
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 @@
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 @@
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 774996e..8bd7991 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -67,6 +67,7 @@
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 @@
private float[] mNewAlphas;
private int mLastChildCount = -1;
private float mTransitionProgress;
+ private Animator mStateAnimator = null;
float mOverScrollEffect = 0f;
@@ -289,6 +291,13 @@
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 @@
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 @@
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 @@
}
}
- @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 @@
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 @@
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 @@
.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 @@
// 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 @@
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 @@
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 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 @@
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 @@
}
}
- 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 (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 ((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 (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 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 @@
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 @@
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 c3853ab..03d43a6 100644
--- a/src/com/android/launcher3/compat/AppWidgetManagerCompatVL.java
+++ b/src/com/android/launcher3/compat/AppWidgetManagerCompatVL.java
@@ -43,7 +43,7 @@
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 6efcc00..5858bc8 100644
--- a/src/com/android/launcher3/compat/LauncherAppsCompat.java
+++ b/src/com/android/launcher3/compat/LauncherAppsCompat.java
@@ -19,8 +19,10 @@
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 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 7e5e6bf..e47b9a5 100644
--- a/src/com/android/launcher3/compat/LauncherAppsCompatV16.java
+++ b/src/com/android/launcher3/compat/LauncherAppsCompatV16.java
@@ -22,7 +22,6 @@
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 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 @@
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 16ad379..601f04c 100644
--- a/src/com/android/launcher3/compat/PackageInstallerCompatVL.java
+++ b/src/com/android/launcher3/compat/PackageInstallerCompatVL.java
@@ -20,6 +20,7 @@
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 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 @@
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 @@
@Override
public void onStop() {
+ mInstaller.unregisterSessionCallback(mCallback);
}
@Override
public void onFinishBind() {
mBound = true;
- replayUpdates(null);
+ mWorker.post(this);
}
@Override
@@ -97,7 +109,7 @@
@Override
public void onResume() {
mResumed = true;
- replayUpdates(null);
+ mWorker.post(this);
}
@Override
@@ -105,13 +117,19 @@
// 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;
}