Merge "Play common transition animations from a common method." into ub-launcher3-master
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 1f908d6..1981b13 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -66,7 +66,7 @@
         android:backupAgent="com.android.launcher3.LauncherBackupAgentHelper"
         android:hardwareAccelerated="true"
         android:icon="@mipmap/ic_launcher_home"
-        android:label="@string/application_name"
+        android:label="@string/app_name"
         android:largeHeap="@bool/config_largeHeap"
         android:restoreAnyVersion="true"
         android:supportsRtl="true" >
@@ -79,6 +79,7 @@
             android:theme="@style/Theme"
             android:windowSoftInputMode="adjustPan"
             android:screenOrientation="nosensor"
+            android:configChanges="keyboard|keyboardHidden|navigation"
             android:resumeWhilePausing="true"
             android:taskAffinity=""
             android:enabled="true">
diff --git a/WallpaperPicker/src/com/android/launcher3/WallpaperCropActivity.java b/WallpaperPicker/src/com/android/launcher3/WallpaperCropActivity.java
index 4be6f17..3554ca7 100644
--- a/WallpaperPicker/src/com/android/launcher3/WallpaperCropActivity.java
+++ b/WallpaperPicker/src/com/android/launcher3/WallpaperCropActivity.java
@@ -108,6 +108,7 @@
                 new View.OnClickListener() {
                     @Override
                     public void onClick(View v) {
+                        actionBar.hide();
                         // Never fade on finish because we return to the app that started us (e.g.
                         // Photos), not the home screen.
                         cropImageAndSetWallpaper(imageUri, null, false /* shouldFadeOutOnFinish */);
diff --git a/WallpaperPicker/src/com/android/launcher3/wallpapertileinfo/DefaultWallpaperInfo.java b/WallpaperPicker/src/com/android/launcher3/wallpapertileinfo/DefaultWallpaperInfo.java
index 7ede260..cf4c35f 100644
--- a/WallpaperPicker/src/com/android/launcher3/wallpapertileinfo/DefaultWallpaperInfo.java
+++ b/WallpaperPicker/src/com/android/launcher3/wallpapertileinfo/DefaultWallpaperInfo.java
@@ -44,7 +44,7 @@
 
             @Override
             public float getParallaxOffset() {
-                return 0;
+                return 0.5f;
             }
         }, null);
     }
diff --git a/WallpaperPicker/src/com/android/photos/BitmapRegionTileSource.java b/WallpaperPicker/src/com/android/photos/BitmapRegionTileSource.java
index 2f9c9a3..4267c41 100644
--- a/WallpaperPicker/src/com/android/photos/BitmapRegionTileSource.java
+++ b/WallpaperPicker/src/com/android/photos/BitmapRegionTileSource.java
@@ -159,6 +159,7 @@
         public enum State { NOT_LOADED, LOADED, ERROR_LOADING };
         private State mState = State.NOT_LOADED;
 
+        /** Returns whether loading was successful. */
         public boolean loadInBackground(InBitmapProvider bitmapProvider) {
             mRotation = getExifRotation();
             mDecoder = loadBitmapRegionDecoder();
@@ -187,7 +188,7 @@
                         try {
                             mPreview = loadPreviewBitmap(opts);
                         } catch (IllegalArgumentException e) {
-                            Log.d(TAG, "Unable to reusage bitmap", e);
+                            Log.d(TAG, "Unable to reuse bitmap", e);
                             opts.inBitmap = null;
                             mPreview = null;
                         }
@@ -196,6 +197,10 @@
                 if (mPreview == null) {
                     mPreview = loadPreviewBitmap(opts);
                 }
+                if (mPreview == null) {
+                    mState = State.ERROR_LOADING;
+                    return false;
+                }
 
                 // Verify that the bitmap can be used on GL surface
                 try {
@@ -206,7 +211,7 @@
                     Log.d(TAG, "Image cannot be rendered on a GL surface", e);
                     mState = State.ERROR_LOADING;
                 }
-                return true;
+                return mState == State.LOADED;
             }
         }
 
@@ -296,7 +301,7 @@
                 Bitmap b = BitmapFactory.decodeStream(is, null, options);
                 Utils.closeSilently(is);
                 return b;
-            } catch (FileNotFoundException e) {
+            } catch (FileNotFoundException | OutOfMemoryError e) {
                 Log.e("BitmapRegionTileSource", "Failed to load URI " + mUri, e);
                 return null;
             }
@@ -378,7 +383,8 @@
                         "Failed to create preview of apropriate size! "
                         + " in: %dx%d, out: %dx%d",
                         mWidth, mHeight,
-                        preview.getWidth(), preview.getHeight()));
+                        preview == null ? -1 : preview.getWidth(),
+                        preview == null ? -1 : preview.getHeight()));
             }
         }
     }
diff --git a/WallpaperPicker/src/com/android/photos/views/TiledImageView.java b/WallpaperPicker/src/com/android/photos/views/TiledImageView.java
index 6f7a530..759613d 100644
--- a/WallpaperPicker/src/com/android/photos/views/TiledImageView.java
+++ b/WallpaperPicker/src/com/android/photos/views/TiledImageView.java
@@ -164,40 +164,6 @@
         }
     }
 
-    private RectF mTempRectF = new RectF();
-    public void positionFromMatrix(Matrix matrix) {
-        if (mRenderer.source != null) {
-            final int rotation = mRenderer.source.getRotation();
-            final boolean swap = !(rotation % 180 == 0);
-            final int width = swap ? mRenderer.source.getImageHeight()
-                    : mRenderer.source.getImageWidth();
-            final int height = swap ? mRenderer.source.getImageWidth()
-                    : mRenderer.source.getImageHeight();
-            mTempRectF.set(0, 0, width, height);
-            matrix.mapRect(mTempRectF);
-            matrix.getValues(mValues);
-            int cx = width / 2;
-            int cy = height / 2;
-            float scale = mValues[Matrix.MSCALE_X];
-            int xoffset = Math.round((getWidth() - mTempRectF.width()) / 2 / scale);
-            int yoffset = Math.round((getHeight() - mTempRectF.height()) / 2 / scale);
-            if (rotation == 90 || rotation == 180) {
-                cx += (mTempRectF.left / scale) - xoffset;
-            } else {
-                cx -= (mTempRectF.left / scale) - xoffset;
-            }
-            if (rotation == 180 || rotation == 270) {
-                cy += (mTempRectF.top / scale) - yoffset;
-            } else {
-                cy -= (mTempRectF.top / scale) - yoffset;
-            }
-            mRenderer.scale = scale;
-            mRenderer.centerX = swap ? cy : cx;
-            mRenderer.centerY = swap ? cx : cy;
-            invalidate();
-        }
-    }
-
     @Thunk class TileRenderer implements Renderer {
 
         private GLES20Canvas mCanvas;
diff --git a/build.gradle b/build.gradle
index d971755..44f5b7c 100644
--- a/build.gradle
+++ b/build.gradle
@@ -3,7 +3,7 @@
         mavenCentral()
     }
     dependencies {
-        classpath 'com.android.tools.build:gradle:1.3.0'
+        classpath 'com.android.tools.build:gradle:+'
         classpath 'com.google.protobuf:protobuf-gradle-plugin:0.7.0'
     }
 }
@@ -21,6 +21,9 @@
         targetSdkVersion 23
         versionCode 1
         versionName "1.0"
+
+        testApplicationId "com.android.launcher3.tests"
+        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
     }
     buildTypes {
         debug {
@@ -30,10 +33,16 @@
     sourceSets {
         main {
             res.srcDirs = ['res', 'WallpaperPicker/res']
-            main.java.srcDirs = ['src', 'WallpaperPicker/src']
+            java.srcDirs = ['src', 'WallpaperPicker/src']
             manifest.srcFile 'AndroidManifest.xml'
             proto.srcDirs 'protos/'
         }
+
+        androidTest {
+            java.srcDirs = ['tests/src']
+            res.srcDirs = ['tests/res']
+            manifest.srcFile "tests/AndroidManifest.xml"
+        }
     }
 }
 
@@ -42,9 +51,13 @@
 }
 
 dependencies {
-    compile 'com.android.support:support-v4:+'
-    compile 'com.android.support:recyclerview-v7:+'
+    compile 'com.android.support:support-v4:23.0.1'
+    compile 'com.android.support:recyclerview-v7:23.0.1'
     compile 'com.google.protobuf.nano:protobuf-javanano:3.0.0-alpha-2'
+
+    testCompile 'junit:junit:4.12'
+    androidTestCompile 'com.android.support.test:runner:+'
+    androidTestCompile 'com.android.support.test.uiautomator:uiautomator-v18:+'
 }
 
 protobuf {
diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml
index 16decfd..2bedb60 100644
--- a/res/values-af/strings.xml
+++ b/res/values-af/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"Launcher3"</string>
+    <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"Werk"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"Program is nie geïnstalleer nie."</string>
@@ -46,6 +46,7 @@
     <string name="permdesc_read_settings" msgid="5833423719057558387">"Laat die program toe om die instellings en kortpaaie in Tuis te lees."</string>
     <string name="permlab_write_settings" msgid="3574213698004620587">"skryf Tuis-instellings en -kortpaaie"</string>
     <string name="permdesc_write_settings" msgid="5440712911516509985">"Laat die program toe om die instellings en kortpaaie in Tuis te verander."</string>
+    <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> word nie toegelaat om foonoproepe te maak nie"</string>
     <string name="gadget_error_text" msgid="6081085226050792095">"Kon nie legstuk laai nie"</string>
     <string name="gadget_setup_text" msgid="8274003207686040488">"Stel op"</string>
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Dit is \'n stelselprogram en kan nie gedeïnstalleer word nie."</string>
diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml
index 5458832..290099a 100644
--- a/res/values-am/strings.xml
+++ b/res/values-am/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"ማስጀመሪያ3"</string>
+    <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"ስራ"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"መተግበሪያ አልተጫነም።"</string>
@@ -46,6 +46,7 @@
     <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="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> የስልክ ጥሪዎችን ለማድረግ አልተፈቀደለትም"</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>
diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml
index dd1c32b..a58ed71 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"Launcher3"</string>
+    <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"العمل"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"لم يتم تثبيت التطبيق."</string>
@@ -46,6 +46,7 @@
     <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="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> غير مسموح به لإجراء مكالمات هاتفية"</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>
diff --git a/res/values-az-rAZ/strings.xml b/res/values-az-rAZ/strings.xml
index 08986d3..29f2cf0 100644
--- a/res/values-az-rAZ/strings.xml
+++ b/res/values-az-rAZ/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"Launcher3"</string>
+    <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"İş"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"Tətbiq quraşdırılmayıb."</string>
@@ -46,6 +46,7 @@
     <string name="permdesc_read_settings" msgid="5833423719057558387">"Tətbiqə Əsas Səhifədə parametrləri və qısayolları oxumağa icazə verir."</string>
     <string name="permlab_write_settings" msgid="3574213698004620587">"Əsas Səhifə ayarlarını və qısayolları yazın"</string>
     <string name="permdesc_write_settings" msgid="5440712911516509985">"Tətbiqə Əsas Səhifədə ayarları və qısayolları dəyişməyə icazə verir."</string>
+    <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> tətbiqinə telefon zəngləri etmək üçün icazə verilmir"</string>
     <string name="gadget_error_text" msgid="6081085226050792095">"Vidcet yükləmə problemi"</string>
     <string name="gadget_setup_text" msgid="8274003207686040488">"Quraşdırma"</string>
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Bu sistem tətbiqi olduğu üçün sistemdən silinə bilməz."</string>
diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml
index 848e56c..6f1a0bc 100644
--- a/res/values-bg/strings.xml
+++ b/res/values-bg/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"Launcher3"</string>
+    <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"Работа"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"Приложението не е инсталирано."</string>
@@ -46,6 +46,7 @@
     <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="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> няма разрешение да извършва телефонни обаждания"</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>
diff --git a/res/values-bn-rBD/strings.xml b/res/values-bn-rBD/strings.xml
index a980623..a8f6496 100644
--- a/res/values-bn-rBD/strings.xml
+++ b/res/values-bn-rBD/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"লঞ্চার৩"</string>
+    <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"কাজ"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"অ্যাপ্লিকেশান ইনস্টল করা নেই৷"</string>
@@ -46,6 +46,7 @@
     <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="msg_no_phone_permission" msgid="9208659281529857371">"ফোন কলগুলি করার জন্য <xliff:g id="APP_NAME">%1$s</xliff:g> এর অনুমতি নেই"</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>
diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml
index 6abccf9..503716f 100644
--- a/res/values-ca/strings.xml
+++ b/res/values-ca/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"Launcher3"</string>
+    <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"Feina"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"L\'aplicació no s\'ha instal·lat."</string>
@@ -46,6 +46,7 @@
     <string name="permdesc_read_settings" msgid="5833423719057558387">"Permet que l\'aplicació llegeixi la configuració i les dreceres de la pantalla d\'inici."</string>
     <string name="permlab_write_settings" msgid="3574213698004620587">"escriu la configuració i les dreceres de la pantalla d\'inici"</string>
     <string name="permdesc_write_settings" msgid="5440712911516509985">"Permet que l\'aplicació canviï la configuració i les dreceres de la pantalla d\'inici."</string>
+    <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> no té permís per fer trucades telefòniques"</string>
     <string name="gadget_error_text" msgid="6081085226050792095">"S\'ha produït un problema en carregar el widget"</string>
     <string name="gadget_setup_text" msgid="8274003207686040488">"Configuració"</string>
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Aquesta aplicació és una aplicació del sistema i no es pot desinstal·lar."</string>
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index d17ac67..4a8daaf 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"Launcher3"</string>
+    <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"Práce"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"Aplikace není nainstalována."</string>
@@ -46,6 +46,7 @@
     <string name="permdesc_read_settings" msgid="5833423719057558387">"Umožňuje aplikaci číst nastavení a odkazy na ploše."</string>
     <string name="permlab_write_settings" msgid="3574213698004620587">"zápis nastavení a odkazů plochy"</string>
     <string name="permdesc_write_settings" msgid="5440712911516509985">"Umožňuje aplikaci změnit nastavení a odkazy na ploše."</string>
+    <string name="msg_no_phone_permission" msgid="9208659281529857371">"Aplikace <xliff:g id="APP_NAME">%1$s</xliff:g> nemá oprávnění telefonovat"</string>
     <string name="gadget_error_text" msgid="6081085226050792095">"Problém s načtením widgetu"</string>
     <string name="gadget_setup_text" msgid="8274003207686040488">"Nastavení"</string>
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Toto je systémová aplikace a nelze ji odinstalovat."</string>
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index 7295354..a904765 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"Launcher3"</string>
+    <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"Arbejde"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"Appen er ikke installeret."</string>
@@ -46,6 +46,7 @@
     <string name="permdesc_read_settings" msgid="5833423719057558387">"Tillader, at appen læser indstillingerne og genvejene på startskærmen."</string>
     <string name="permlab_write_settings" msgid="3574213698004620587">"skrive indstillinger og genveje for startskærmen"</string>
     <string name="permdesc_write_settings" msgid="5440712911516509985">"Tillader, at appen ændrer indstillingerne og genvejene på startskærmen."</string>
+    <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> har ikke tilladelse til at foretage telefonopkald"</string>
     <string name="gadget_error_text" msgid="6081085226050792095">"Der er problemer med indlæsning af widgetten"</string>
     <string name="gadget_setup_text" msgid="8274003207686040488">"Konfigurer"</string>
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Dette er en systemapp, som ikke kan afinstalleres."</string>
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index e4834a3..e201d21 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"Launcher3"</string>
+    <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"Arbeit"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"App ist nicht installiert."</string>
@@ -46,6 +46,7 @@
     <string name="permdesc_read_settings" msgid="5833423719057558387">"Ermöglicht der App, die Einstellungen und Verknüpfungen auf dem Startbildschirm zu lesen"</string>
     <string name="permlab_write_settings" msgid="3574213698004620587">"Einstellungen und Verknüpfungen für den Startbildschirm schreiben"</string>
     <string name="permdesc_write_settings" msgid="5440712911516509985">"Ermöglicht der App, die Einstellungen und Verknüpfungen auf dem Startbildschirm zu ändern"</string>
+    <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> darf keine Telefonanrufe tätigen."</string>
     <string name="gadget_error_text" msgid="6081085226050792095">"Problem beim Laden des Widgets"</string>
     <string name="gadget_setup_text" msgid="8274003207686040488">"Einrichten"</string>
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Dies ist eine Systemanwendung, die nicht deinstalliert werden kann."</string>
diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml
index c5b3c87..ff6ff1d 100644
--- a/res/values-el/strings.xml
+++ b/res/values-el/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"Launcher3"</string>
+    <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"Εργασία"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"Η εφαρμογή δεν έχει εγκατασταθεί."</string>
@@ -46,6 +46,7 @@
     <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="msg_no_phone_permission" msgid="9208659281529857371">"Η εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> δεν επιτρέπεται να πραγματοποιεί τηλεφωνικές κλήσεις"</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>
diff --git a/res/values-en-rAU/strings.xml b/res/values-en-rAU/strings.xml
index d959403..f4a8639 100644
--- a/res/values-en-rAU/strings.xml
+++ b/res/values-en-rAU/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"Launcher3"</string>
+    <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"Work"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"App isn\'t installed."</string>
@@ -46,6 +46,7 @@
     <string name="permdesc_read_settings" msgid="5833423719057558387">"Allows the app to read the settings and shortcuts in Home."</string>
     <string name="permlab_write_settings" msgid="3574213698004620587">"write Home settings and shortcuts"</string>
     <string name="permdesc_write_settings" msgid="5440712911516509985">"Allows the app to change the settings and shortcuts in Home."</string>
+    <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> is not allowed to make phone calls"</string>
     <string name="gadget_error_text" msgid="6081085226050792095">"Problem loading widget"</string>
     <string name="gadget_setup_text" msgid="8274003207686040488">"Setup"</string>
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"This is a system app and can\'t be uninstalled."</string>
diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml
index d959403..f4a8639 100644
--- a/res/values-en-rGB/strings.xml
+++ b/res/values-en-rGB/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"Launcher3"</string>
+    <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"Work"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"App isn\'t installed."</string>
@@ -46,6 +46,7 @@
     <string name="permdesc_read_settings" msgid="5833423719057558387">"Allows the app to read the settings and shortcuts in Home."</string>
     <string name="permlab_write_settings" msgid="3574213698004620587">"write Home settings and shortcuts"</string>
     <string name="permdesc_write_settings" msgid="5440712911516509985">"Allows the app to change the settings and shortcuts in Home."</string>
+    <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> is not allowed to make phone calls"</string>
     <string name="gadget_error_text" msgid="6081085226050792095">"Problem loading widget"</string>
     <string name="gadget_setup_text" msgid="8274003207686040488">"Setup"</string>
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"This is a system app and can\'t be uninstalled."</string>
diff --git a/res/values-en-rIN/strings.xml b/res/values-en-rIN/strings.xml
index d959403..f4a8639 100644
--- a/res/values-en-rIN/strings.xml
+++ b/res/values-en-rIN/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"Launcher3"</string>
+    <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"Work"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"App isn\'t installed."</string>
@@ -46,6 +46,7 @@
     <string name="permdesc_read_settings" msgid="5833423719057558387">"Allows the app to read the settings and shortcuts in Home."</string>
     <string name="permlab_write_settings" msgid="3574213698004620587">"write Home settings and shortcuts"</string>
     <string name="permdesc_write_settings" msgid="5440712911516509985">"Allows the app to change the settings and shortcuts in Home."</string>
+    <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> is not allowed to make phone calls"</string>
     <string name="gadget_error_text" msgid="6081085226050792095">"Problem loading widget"</string>
     <string name="gadget_setup_text" msgid="8274003207686040488">"Setup"</string>
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"This is a system app and can\'t be uninstalled."</string>
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
index 669c818..5246945 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"Launcher3"</string>
+    <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"Trabajo"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"No se instaló la aplicación."</string>
@@ -46,6 +46,7 @@
     <string name="permdesc_read_settings" msgid="5833423719057558387">"Permite que la aplicación lea la configuración y los accesos directos de la pantalla principal."</string>
     <string name="permlab_write_settings" msgid="3574213698004620587">"escribir configuración y accesos directos de la pantalla principal"</string>
     <string name="permdesc_write_settings" msgid="5440712911516509985">"Permite que la aplicación cambie la configuración y los accesos directos de la pantalla principal."</string>
+    <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> no puede realizar llamadas telefónicas"</string>
     <string name="gadget_error_text" msgid="6081085226050792095">"Problema al cargar el widget"</string>
     <string name="gadget_setup_text" msgid="8274003207686040488">"Configuración"</string>
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Esta es una aplicación del sistema y no se puede desinstalar."</string>
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index 86136cc..c160aa3 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"Launcher3"</string>
+    <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"Trabajo"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"La aplicación no está instalada."</string>
@@ -46,6 +46,7 @@
     <string name="permdesc_read_settings" msgid="5833423719057558387">"Permite que la aplicación consulte los ajustes y los accesos directos de la pantalla de inicio."</string>
     <string name="permlab_write_settings" msgid="3574213698004620587">"escribir información de accesos directos y de ajustes de la pantalla de inicio"</string>
     <string name="permdesc_write_settings" msgid="5440712911516509985">"Permite que las aplicaciones cambien los ajustes y los accesos directos de la pantalla de inicio."</string>
+    <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> no puede hacer llamadas"</string>
     <string name="gadget_error_text" msgid="6081085226050792095">"Problema al cargar el widget"</string>
     <string name="gadget_setup_text" msgid="8274003207686040488">"Configuración"</string>
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Esta aplicación es del sistema y no se puede desinstalar."</string>
diff --git a/res/values-et-rEE/strings.xml b/res/values-et-rEE/strings.xml
index c18dd46..0065b4e 100644
--- a/res/values-et-rEE/strings.xml
+++ b/res/values-et-rEE/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"Launcher3"</string>
+    <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"Töö"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"Rakendus pole installitud."</string>
@@ -46,6 +46,7 @@
     <string name="permdesc_read_settings" msgid="5833423719057558387">"Võimaldab rakendusel lugeda avaekraanil seadeid ja otseteid."</string>
     <string name="permlab_write_settings" msgid="3574213698004620587">"kirjuta avaekraani seaded ja otseteed"</string>
     <string name="permdesc_write_settings" msgid="5440712911516509985">"Võimaldab rakendusel muuta avaekraanil seadeid ja otseteid."</string>
+    <string name="msg_no_phone_permission" msgid="9208659281529857371">"Rakendusel <xliff:g id="APP_NAME">%1$s</xliff:g> pole lubatud helistada"</string>
     <string name="gadget_error_text" msgid="6081085226050792095">"Probleem vidina laadimisel"</string>
     <string name="gadget_setup_text" msgid="8274003207686040488">"Seadistamine"</string>
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"See on süsteemirakendus ja seda ei saa desinstallida."</string>
diff --git a/res/values-eu-rES/strings.xml b/res/values-eu-rES/strings.xml
index 03d66ee..84653e3 100644
--- a/res/values-eu-rES/strings.xml
+++ b/res/values-eu-rES/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"Abiarazlea3"</string>
+    <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"Lana"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"Aplikazioa instalatu gabe dago."</string>
@@ -46,6 +46,7 @@
     <string name="permdesc_read_settings" msgid="5833423719057558387">"Hasierako pantailako ezarpenak eta lasterbideak irakurtzea baimentzen die aplikazioei."</string>
     <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="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> aplikazioak ez du telefono-deiak egiteko baimenik"</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>
diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml
index 94afcfc..91fc0d3 100644
--- a/res/values-fa/strings.xml
+++ b/res/values-fa/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"Launcher3"</string>
+    <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"کاری"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"برنامه نصب نشده است."</string>
@@ -46,6 +46,7 @@
     <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="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> مجاز نیست تماس تلفنی برقرار کند"</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>
diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml
index 1a691ef..b7578c6 100644
--- a/res/values-fi/strings.xml
+++ b/res/values-fi/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"Launcher3"</string>
+    <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"Työ"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"Sovellusta ei ole asennettu."</string>
@@ -46,6 +46,7 @@
     <string name="permdesc_read_settings" msgid="5833423719057558387">"Antaa sovelluksen lukea aloitusruudun asetukset ja pikakuvakkeet."</string>
     <string name="permlab_write_settings" msgid="3574213698004620587">"kirjoita aloitusruudun asetuksia ja pikakuvakkeita"</string>
     <string name="permdesc_write_settings" msgid="5440712911516509985">"Antaa sovelluksen muuttaa aloitusruudun asetuksia ja pikakuvakkeita."</string>
+    <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> ei saa soittaa puheluita."</string>
     <string name="gadget_error_text" msgid="6081085226050792095">"Ongelma ladattaessa widgetiä"</string>
     <string name="gadget_setup_text" msgid="8274003207686040488">"Asetus"</string>
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Tämä on järjestelmäsovellus, eikä sitä voi poistaa."</string>
diff --git a/res/values-fr-rCA/strings.xml b/res/values-fr-rCA/strings.xml
index f016c6d..ca6eccc 100644
--- a/res/values-fr-rCA/strings.xml
+++ b/res/values-fr-rCA/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"Lanceur3"</string>
+    <string name="app_name" msgid="649227358658669779">"Lanceur3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"Travail"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"L\'application n\'est pas installée."</string>
@@ -46,6 +46,7 @@
     <string name="permdesc_read_settings" msgid="5833423719057558387">"Permet à l\'application de lire les paramètres et les raccourcis de l\'écran d\'accueil."</string>
     <string name="permlab_write_settings" msgid="3574213698004620587">"enregistrer les paramètres de la page d\'accueil et des raccourcis"</string>
     <string name="permdesc_write_settings" msgid="5440712911516509985">"Permet à l\'application de modifier les paramètres et les raccourcis de l\'écran d\'accueil."</string>
+    <string name="msg_no_phone_permission" msgid="9208659281529857371">"L\'application <xliff:g id="APP_NAME">%1$s</xliff:g> n\'est pas autorisée à faire des appels téléphoniques"</string>
     <string name="gadget_error_text" msgid="6081085226050792095">"Problème lors du chargement du widget"</string>
     <string name="gadget_setup_text" msgid="8274003207686040488">"Configuration"</string>
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Impossible de désinstaller cette application, car il s\'agit d\'une application système."</string>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index b6fac01..58a0fb7 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"Launcher3"</string>
+    <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"Android Work"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"L\'application n\'est pas installée."</string>
@@ -46,6 +46,7 @@
     <string name="permdesc_read_settings" msgid="5833423719057558387">"Permettre à l\'application de lire les paramètres et les raccourcis de l\'écran d\'accueil"</string>
     <string name="permlab_write_settings" msgid="3574213698004620587">"modifier les paramètres et les raccourcis de l\'écran d\'accueil"</string>
     <string name="permdesc_write_settings" msgid="5440712911516509985">"Permettre à l\'application de modifier les paramètres et les raccourcis de l\'écran d\'accueil"</string>
+    <string name="msg_no_phone_permission" msgid="9208659281529857371">"L\'application <xliff:g id="APP_NAME">%1$s</xliff:g> n\'est pas autorisée à passer des appels téléphoniques."</string>
     <string name="gadget_error_text" msgid="6081085226050792095">"Problème lors du chargement du widget."</string>
     <string name="gadget_setup_text" msgid="8274003207686040488">"Configuration"</string>
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Impossible de désinstaller cette application, car il s\'agit d\'une application système."</string>
diff --git a/res/values-gl-rES/strings.xml b/res/values-gl-rES/strings.xml
index 71cf482..9e5a605 100644
--- a/res/values-gl-rES/strings.xml
+++ b/res/values-gl-rES/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"Launcher3"</string>
+    <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"Traballo"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"A aplicación non está instalada"</string>
@@ -46,6 +46,7 @@
     <string name="permdesc_read_settings" msgid="5833423719057558387">"Permite a unha aplicación ler a configuración e os atallos da páxina de inicio."</string>
     <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="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> non ten permiso para facer chamadas telefónicas"</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>
diff --git a/res/values-gu-rIN/strings.xml b/res/values-gu-rIN/strings.xml
index e4b8281..129d83e 100644
--- a/res/values-gu-rIN/strings.xml
+++ b/res/values-gu-rIN/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"Launcher3"</string>
+    <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"કાર્યાલય"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"એપ્લિકેશન ઇન્સ્ટોલ થઈ નથી."</string>
@@ -46,6 +46,7 @@
     <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="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> ને ફોન કૉલ્સ કરવાની મંજૂરી નથી"</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>
diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml
index eddef94..b209cee 100644
--- a/res/values-hi/strings.xml
+++ b/res/values-hi/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"Launcher3"</string>
+    <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"कार्यस्‍थल"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"एप्‍लिकेशन इंस्‍टॉल नहीं है."</string>
@@ -46,6 +46,7 @@
     <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="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> को फ़ोन कॉल करने की अनुमति नहीं है"</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>
diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml
index 8cb2c03..ec9f892 100644
--- a/res/values-hr/strings.xml
+++ b/res/values-hr/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"Pokretač3"</string>
+    <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"Posao"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"Aplikacija nije instalirana."</string>
@@ -46,6 +46,7 @@
     <string name="permdesc_read_settings" msgid="5833423719057558387">"Aplikaciji omogućuje čitanje postavki i prečaca na početnom zaslonu."</string>
     <string name="permlab_write_settings" msgid="3574213698004620587">"pisanje postavki početnog zaslona i prečaca"</string>
     <string name="permdesc_write_settings" msgid="5440712911516509985">"Aplikaciji omogućuje promjenu postavki i prečaca na početnom zaslonu."</string>
+    <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> nema dopuštenje za telefonske pozive"</string>
     <string name="gadget_error_text" msgid="6081085226050792095">"Problem pri učitavanju widgeta"</string>
     <string name="gadget_setup_text" msgid="8274003207686040488">"Postavljanje"</string>
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Ovo je aplikacija sustava i ne može se ukloniti."</string>
diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml
index aa1f967..cfff315 100644
--- a/res/values-hu/strings.xml
+++ b/res/values-hu/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"Launcher3"</string>
+    <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"Munka"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"Az alkalmazás nincs telepítve."</string>
@@ -46,6 +46,7 @@
     <string name="permdesc_read_settings" msgid="5833423719057558387">"Lehetővé teszi az alkalmazás számára, hogy beolvassa a kezdőképernyő beállításait és parancsikonjait."</string>
     <string name="permlab_write_settings" msgid="3574213698004620587">"Főoldal beállításainak és parancsikonjainak írása"</string>
     <string name="permdesc_write_settings" msgid="5440712911516509985">"Lehetővé teszi az alkalmazás számára, hogy módosítsa a kezdőképernyő beállításait és parancsikonjait."</string>
+    <string name="msg_no_phone_permission" msgid="9208659281529857371">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> nem kezdeményezhet telefonhívásokat"</string>
     <string name="gadget_error_text" msgid="6081085226050792095">"Probléma történt a modul betöltésekor"</string>
     <string name="gadget_setup_text" msgid="8274003207686040488">"Beállítás"</string>
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Ez egy rendszeralkalmazás, és nem lehet eltávolítani."</string>
diff --git a/res/values-hy-rAM/strings.xml b/res/values-hy-rAM/strings.xml
index f3d77c5..8beff3a 100644
--- a/res/values-hy-rAM/strings.xml
+++ b/res/values-hy-rAM/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"Launcher3"</string>
+    <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"Աշխատանքային"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"Ծրագիրը տեղադրված չէ:"</string>
@@ -46,6 +46,7 @@
     <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="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածին չի թույլատրվում հեռախոսազանգեր կատարել"</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>
diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml
index d27bbff..3de54af 100644
--- a/res/values-in/strings.xml
+++ b/res/values-in/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"Launcher3"</string>
+    <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"Kantor"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"Aplikasi tidak dipasang."</string>
@@ -46,6 +46,7 @@
     <string name="permdesc_read_settings" msgid="5833423719057558387">"Mengizinkan aplikasi membaca setelan dan pintasan di layar Utama."</string>
     <string name="permlab_write_settings" msgid="3574213698004620587">"menulis setelan dan pintasan layar Utama"</string>
     <string name="permdesc_write_settings" msgid="5440712911516509985">"Mengizinkan aplikasi mengubah setelan dan pintasan di layar Utama."</string>
+    <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> tidak diizinkan untuk melakukan panggilan telepon"</string>
     <string name="gadget_error_text" msgid="6081085226050792095">"Masalah memuat widget"</string>
     <string name="gadget_setup_text" msgid="8274003207686040488">"Siapkan"</string>
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Ini adalah aplikasi sistem dan tidak dapat dicopot pemasangannya."</string>
diff --git a/res/values-is-rIS/strings.xml b/res/values-is-rIS/strings.xml
index 6fbedb5..eb900be 100644
--- a/res/values-is-rIS/strings.xml
+++ b/res/values-is-rIS/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"Launcher3"</string>
+    <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"Vinna"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"Forritið er ekki uppsett."</string>
@@ -46,6 +46,7 @@
     <string name="permdesc_read_settings" msgid="5833423719057558387">"Leyfir forriti að lesa stillingar og flýtileiðir heimaskjás."</string>
     <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="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> hefur ekki leyfi til að hringja símtöl"</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>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index 24eae89..7a1585d 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"Launcher3"</string>
+    <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"Lavoro"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"App non installata."</string>
@@ -46,6 +46,7 @@
     <string name="permdesc_read_settings" msgid="5833423719057558387">"Consente all\'app di leggere le impostazioni e le scorciatoie in Home."</string>
     <string name="permlab_write_settings" msgid="3574213698004620587">"creazione di impostazioni e scorciatoie in Home"</string>
     <string name="permdesc_write_settings" msgid="5440712911516509985">"Consente all\'app di modificare le impostazioni e le scorciatoie in Home."</string>
+    <string name="msg_no_phone_permission" msgid="9208659281529857371">"L\'app <xliff:g id="APP_NAME">%1$s</xliff:g> non è autorizzata a effettuare telefonate"</string>
     <string name="gadget_error_text" msgid="6081085226050792095">"Errore durante il caricamento del widget"</string>
     <string name="gadget_setup_text" msgid="8274003207686040488">"Configurazione"</string>
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Questa è un\'app di sistema e non può essere disinstallata."</string>
diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml
index 7f69eed..5b978af 100644
--- a/res/values-iw/strings.xml
+++ b/res/values-iw/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"Launcher3"</string>
+    <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"עבודה"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"האפליקציה לא מותקנת."</string>
@@ -46,6 +46,7 @@
     <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="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> אינו רשאי להתקשר"</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>
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index 14d6391..662e291 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"Launcher3"</string>
+    <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"仕事用"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"このアプリはインストールされていません。"</string>
@@ -46,6 +46,7 @@
     <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="msg_no_phone_permission" msgid="9208659281529857371">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」から電話をかけることはできません"</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>
diff --git a/res/values-ka-rGE/strings.xml b/res/values-ka-rGE/strings.xml
index 60c7cb6..bf5724f 100644
--- a/res/values-ka-rGE/strings.xml
+++ b/res/values-ka-rGE/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"Launcher3"</string>
+    <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"სამუშაო"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"აპი არ არის დაყენებული."</string>
@@ -46,6 +46,7 @@
     <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="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g>-ს არ აქვს სატელეფონო ზარების განხორციელების უფლება"</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>
diff --git a/res/values-kk-rKZ/strings.xml b/res/values-kk-rKZ/strings.xml
index 8a95407..61a423a 100644
--- a/res/values-kk-rKZ/strings.xml
+++ b/res/values-kk-rKZ/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"Launcher3"</string>
+    <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"Жұмыс"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"Қолданба орнатылмаған."</string>
@@ -46,6 +46,7 @@
     <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="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> арқылы телефон қоңырауларын соғуға рұқсат етілмеген"</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>
diff --git a/res/values-km-rKH/strings.xml b/res/values-km-rKH/strings.xml
index eb28cf9..1a4469d 100644
--- a/res/values-km-rKH/strings.xml
+++ b/res/values-km-rKH/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"Launcher3"</string>
+    <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"ការងារ"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"មិន​បាន​ដំឡើង​កម្មវិធី។"</string>
@@ -46,6 +46,7 @@
     <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="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> មិនត្រូវបានអនុញ្ញាតឲ្យធ្វើការហៅទូរស័ព្ទទេ"</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>
diff --git a/res/values-kn-rIN/strings.xml b/res/values-kn-rIN/strings.xml
index b581308..e712ba8 100644
--- a/res/values-kn-rIN/strings.xml
+++ b/res/values-kn-rIN/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"ಲಾಂಚರ್3"</string>
+    <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"ಕೆಲಸ"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"ಅಪ್ಲಿಕೇಶನ್‌ ಅನ್ನು ಸ್ಥಾಪಿಸಲಾಗಿಲ್ಲ"</string>
@@ -46,6 +46,7 @@
     <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="msg_no_phone_permission" msgid="9208659281529857371">"ಫೋನ್ ಕರೆಗಳನ್ನು ಮಾಡಲು <xliff:g id="APP_NAME">%1$s</xliff:g> ಅಪ್ಲಿಕೇಶನ್‌‌ಗೆ ಅನುಮತಿಸಲಾಗುವುದಿಲ್ಲ"</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>
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index 77bad78..b7c1a50 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"Launcher3"</string>
+    <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"업무"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"앱이 설치되지 않았습니다."</string>
@@ -46,6 +46,7 @@
     <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="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g>에서 전화를 걸 수 없습니다."</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>
diff --git a/res/values-ky-rKG/strings.xml b/res/values-ky-rKG/strings.xml
index 68e9162..53c3f88 100644
--- a/res/values-ky-rKG/strings.xml
+++ b/res/values-ky-rKG/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"Launcher3"</string>
+    <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"Жумуш"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"Колдонмо орнотулган эмес."</string>
@@ -46,6 +46,7 @@
     <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="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> телефон чалууларды аткарууга уруксаты жок"</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>
diff --git a/res/values-lo-rLA/strings.xml b/res/values-lo-rLA/strings.xml
index 42ed281..6d19f31 100644
--- a/res/values-lo-rLA/strings.xml
+++ b/res/values-lo-rLA/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"Launcher3"</string>
+    <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"ວຽກ"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"ແອັບຯບໍ່ໄດ້ຖືກຕິດຕັ້ງ."</string>
@@ -46,6 +46,7 @@
     <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="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> ບໍ່​ໄດ້​ຮັບ​ອະ​ນຸ​ຍາດ​ໃຫ້​ໂທ"</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>
diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml
index fa02e93..1336a4d 100644
--- a/res/values-lt/strings.xml
+++ b/res/values-lt/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"Launcher3"</string>
+    <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"Darbas"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"Programa neįdiegta."</string>
@@ -46,6 +46,7 @@
     <string name="permdesc_read_settings" msgid="5833423719057558387">"Programai leidžiama skaityti pagrindinio puslapio nustatymus ir sparčiuosius klavišus."</string>
     <string name="permlab_write_settings" msgid="3574213698004620587">"rašyti pagrindinio puslapio nustatymus ir sparčiuosius klavišus"</string>
     <string name="permdesc_write_settings" msgid="5440712911516509985">"Programai leidžiama keisti pagrindinio puslapio nustatymus ir sparčiuosius klavišus."</string>
+    <string name="msg_no_phone_permission" msgid="9208659281529857371">"„<xliff:g id="APP_NAME">%1$s</xliff:g>“ neleidžiama skambinti"</string>
     <string name="gadget_error_text" msgid="6081085226050792095">"Problema įkeliant valdiklį"</string>
     <string name="gadget_setup_text" msgid="8274003207686040488">"Sąranka"</string>
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Tai sistemos programa ir jos negalima pašalinti."</string>
diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml
index 404064e..4e2f98e 100644
--- a/res/values-lv/strings.xml
+++ b/res/values-lv/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"Launcher3"</string>
+    <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"Darbs"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"Lietotne nav instalēta."</string>
@@ -46,6 +46,7 @@
     <string name="permdesc_read_settings" msgid="5833423719057558387">"Ļauj lietotnei lasīt iestatījumus un saīsnes sākuma ekrānā."</string>
     <string name="permlab_write_settings" msgid="3574213698004620587">"rakstīt sākuma ekrāna iestatījumus un saīsnes"</string>
     <string name="permdesc_write_settings" msgid="5440712911516509985">"Ļauj lietotnei mainīt iestatījumus un saīsnes sākuma ekrānā."</string>
+    <string name="msg_no_phone_permission" msgid="9208659281529857371">"Lietotnei <xliff:g id="APP_NAME">%1$s</xliff:g> nav atļauts veikt tālruņa zvanus."</string>
     <string name="gadget_error_text" msgid="6081085226050792095">"Ielādējot logrīku, radās problēma."</string>
     <string name="gadget_setup_text" msgid="8274003207686040488">"Notiek iestatīšana"</string>
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Šī ir sistēmas lietotne, un to nevar atinstalēt."</string>
diff --git a/res/values-mk-rMK/strings.xml b/res/values-mk-rMK/strings.xml
index 88fbbda..834598a 100644
--- a/res/values-mk-rMK/strings.xml
+++ b/res/values-mk-rMK/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"Launcher3"</string>
+    <string name="app_name" msgid="649227358658669779">"Стартер3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"Работа"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"Апликацијата не е инсталирана."</string>
@@ -46,6 +46,7 @@
     <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="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> нема дозвола за телефонски повици"</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>
diff --git a/res/values-ml-rIN/strings.xml b/res/values-ml-rIN/strings.xml
index a956f46..eb48c7c 100644
--- a/res/values-ml-rIN/strings.xml
+++ b/res/values-ml-rIN/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"Launcher3"</string>
+    <string name="app_name" msgid="649227358658669779">"ലോഞ്ചർ3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"ഔദ്യോഗികം"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"അപ്ലിക്കേഷൻ ഇൻസ്‌റ്റാളുചെ‌യ്‌തിട്ടില്ല."</string>
@@ -46,6 +46,7 @@
     <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="msg_no_phone_permission" msgid="9208659281529857371">"ഫോൺ കോൾ ചെയ്യാൻ <xliff:g id="APP_NAME">%1$s</xliff:g> എന്നതിനെ അനുവദിച്ചിട്ടില്ല"</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>
diff --git a/res/values-mn-rMN/strings.xml b/res/values-mn-rMN/strings.xml
index 8b8715d..07eaf15 100644
--- a/res/values-mn-rMN/strings.xml
+++ b/res/values-mn-rMN/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"Launcher3"</string>
+    <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"Ажил"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"Апп суугаагүй байна."</string>
@@ -46,6 +46,7 @@
     <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="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> утасны дуудлага хийх боломжгүй"</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>
diff --git a/res/values-mr-rIN/strings.xml b/res/values-mr-rIN/strings.xml
index 0bc756d..c9fa78d 100644
--- a/res/values-mr-rIN/strings.xml
+++ b/res/values-mr-rIN/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"Launcher3"</string>
+    <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"कार्य"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"अॅप स्थापित केलेला नाही."</string>
@@ -46,6 +46,7 @@
     <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="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> ला फोन कॉल करण्याची अनुमती नाही"</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>
diff --git a/res/values-ms-rMY/strings.xml b/res/values-ms-rMY/strings.xml
index c15b52d..55de172 100644
--- a/res/values-ms-rMY/strings.xml
+++ b/res/values-ms-rMY/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"Launcher3"</string>
+    <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"Kerja"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"Apl tidak dipasang."</string>
@@ -46,6 +46,7 @@
     <string name="permdesc_read_settings" msgid="5833423719057558387">"Membenarkan apl membaca tetapan dan pintasan di Laman Utama."</string>
     <string name="permlab_write_settings" msgid="3574213698004620587">"tulis tetapan dan pintasan Laman Utama"</string>
     <string name="permdesc_write_settings" msgid="5440712911516509985">"Membenarkan apl menukar tetapan dan pintasan di Laman Utama."</string>
+    <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> tidak dibenarkan membuat panggilan telefon"</string>
     <string name="gadget_error_text" msgid="6081085226050792095">"Masalah memuatkan widget"</string>
     <string name="gadget_setup_text" msgid="8274003207686040488">"Persediaan"</string>
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Ini ialah apl sistem dan tidak boleh dinyahpasang."</string>
diff --git a/res/values-my-rMM/strings.xml b/res/values-my-rMM/strings.xml
index 395f32d..c47f2e6 100644
--- a/res/values-my-rMM/strings.xml
+++ b/res/values-my-rMM/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"Launcher၃"</string>
+    <string name="app_name" msgid="649227358658669779">"ဖွင့်တင်စက်၃"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"အလုပ်"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"အပ်ပလီကေးရှင်း မထည့်သွင်းထားပါ"</string>
@@ -46,6 +46,7 @@
     <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="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g>သည် ဖုန်းခေါ်ဆိုခွင့် မရှိပါ"</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>
diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
index 8ea97a1..575d591 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"Launcher3"</string>
+    <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"Jobb"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"Appen er ikke installert."</string>
@@ -46,6 +46,7 @@
     <string name="permdesc_read_settings" msgid="5833423719057558387">"Lar appen lese innstillingene og snarveiene på startsiden."</string>
     <string name="permlab_write_settings" msgid="3574213698004620587">"angi startsideinnstillinger og -snarveier"</string>
     <string name="permdesc_write_settings" msgid="5440712911516509985">"Lar appen endre innstillingene og snarveiene på startsiden."</string>
+    <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> har ikke tillatelse til å ringe"</string>
     <string name="gadget_error_text" msgid="6081085226050792095">"Problem ved innlasting av modul"</string>
     <string name="gadget_setup_text" msgid="8274003207686040488">"Konfigurering"</string>
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Dette er en systemapp som ikke kan avinstalleres."</string>
diff --git a/res/values-ne-rNP/strings.xml b/res/values-ne-rNP/strings.xml
index a749226..f197979 100644
--- a/res/values-ne-rNP/strings.xml
+++ b/res/values-ne-rNP/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"Launcher3"</string>
+    <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"कार्य"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"अनुप्रयोग स्थापित छैन।"</string>
@@ -46,6 +46,7 @@
     <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="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> ले फोन कलहरू गर्न अनुमति छैन"</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>
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index 8e21499..0d34144 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"Launcher3"</string>
+    <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"Werk"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"App is niet geïnstalleerd."</string>
@@ -46,6 +46,7 @@
     <string name="permdesc_read_settings" msgid="5833423719057558387">"De app toestaan de instellingen en snelkoppelingen op de startpagina te lezen."</string>
     <string name="permlab_write_settings" msgid="3574213698004620587">"instellingen en snelkoppelingen op de startpagina schrijven"</string>
     <string name="permdesc_write_settings" msgid="5440712911516509985">"De app toestaan de instellingen en snelkoppelingen op de startpagina te wijzigen."</string>
+    <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> mag niet bellen"</string>
     <string name="gadget_error_text" msgid="6081085226050792095">"Probleem bij het laden van widget"</string>
     <string name="gadget_setup_text" msgid="8274003207686040488">"Configuratie"</string>
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Dit is een systeemapp die niet kan worden verwijderd."</string>
diff --git a/res/values-pa-rIN/strings.xml b/res/values-pa-rIN/strings.xml
index 8f0956d..5647afe 100644
--- a/res/values-pa-rIN/strings.xml
+++ b/res/values-pa-rIN/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"ਲਾਂਚਰ3"</string>
+    <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"ਦਫ਼ਤਰ"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"ਐਪ ਇੰਸਟੌਲ ਨਹੀਂ ਕੀਤਾ ਹੋਇਆ ਹੈ।"</string>
@@ -46,6 +46,7 @@
     <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="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਨੂੰ ਫੋਨ ਕਾਲਾਂ ਕਰਨ ਦੀ ਆਗਿਆ ਨਹੀਂ ਹੈ"</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>
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
index 2824a49..5ebd6dc 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"Launcher3"</string>
+    <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"Praca"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"Aplikacja nie jest zainstalowana."</string>
@@ -46,6 +46,7 @@
     <string name="permdesc_read_settings" msgid="5833423719057558387">"Pozwala aplikacji na odczytywanie ustawień i skrótów na ekranie głównym."</string>
     <string name="permlab_write_settings" msgid="3574213698004620587">"zapisywanie ustawień i skrótów na ekranie głównym"</string>
     <string name="permdesc_write_settings" msgid="5440712911516509985">"Umożliwia aplikacji zmianę ustawień i skrótów na ekranie głównym."</string>
+    <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> nie może wykonywać połączeń telefonicznych"</string>
     <string name="gadget_error_text" msgid="6081085226050792095">"Problem podczas ładowania widżetu"</string>
     <string name="gadget_setup_text" msgid="8274003207686040488">"Konfiguracja"</string>
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"To aplikacja systemowa i nie można jej odinstalować."</string>
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
index f8e1562..004b802 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"Iniciador3"</string>
+    <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"Trabalho"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"A aplicação não está instalada."</string>
@@ -46,6 +46,7 @@
     <string name="permdesc_read_settings" msgid="5833423719057558387">"Permite à aplicação ler as definições e os atalhos no Ecrã Principal."</string>
     <string name="permlab_write_settings" msgid="3574213698004620587">"escrever definições e atalhos do Ecrã principal"</string>
     <string name="permdesc_write_settings" msgid="5440712911516509985">"Permite à aplicação alterar as definições e os atalhos no Ecrã Principal."</string>
+    <string name="msg_no_phone_permission" msgid="9208659281529857371">"O <xliff:g id="APP_NAME">%1$s</xliff:g> não tem autorização para efetuar chamadas telefónicas"</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">"É uma aplicação de sistema e não pode ser desinstalada."</string>
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index 88d7cd5..a2c254e 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"Launcher3"</string>
+    <string name="app_name" msgid="649227358658669779">"Tela de início 3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"Trabalho"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"O app não está instalado."</string>
@@ -46,6 +46,7 @@
     <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 app altere as configurações e os atalhos na tela inicial."</string>
+    <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> não tem permissão para fazer chamadas"</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 app do sistema e não pode ser desinstalado."</string>
diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml
index 56dac5d..afa5679 100644
--- a/res/values-ro/strings.xml
+++ b/res/values-ro/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"Launcher3"</string>
+    <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"Work"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"Aplicația nu este instalată."</string>
@@ -46,6 +46,7 @@
     <string name="permdesc_read_settings" msgid="5833423719057558387">"Permite aplicației să citească setările și comenzile rapide din ecranul de pornire."</string>
     <string name="permlab_write_settings" msgid="3574213698004620587">"scrie setări și comenzi rapide pentru ecranul de pornire"</string>
     <string name="permdesc_write_settings" msgid="5440712911516509985">"Permite aplicației să modifice setările și comenzile rapide din ecranul de pornire."</string>
+    <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> nu are permisiunea de a apela"</string>
     <string name="gadget_error_text" msgid="6081085226050792095">"Problemă la încărcarea widgetului"</string>
     <string name="gadget_setup_text" msgid="8274003207686040488">"Configurați"</string>
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Aceasta este o aplicație de sistem și nu poate fi dezinstalată."</string>
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index 837c102..a4e70bb 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"Launcher3"</string>
+    <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"Работа"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"Приложение удалено"</string>
@@ -46,6 +46,7 @@
     <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="msg_no_phone_permission" msgid="9208659281529857371">"Приложение <xliff:g id="APP_NAME">%1$s</xliff:g> не может делать телефонные звонки"</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>
diff --git a/res/values-si-rLK/strings.xml b/res/values-si-rLK/strings.xml
index 9b713e9..e9f06fc 100644
--- a/res/values-si-rLK/strings.xml
+++ b/res/values-si-rLK/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"Launcher3"</string>
+    <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"කාර්යාලය"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"යෙදුම ස්ථාපනය කර නැත."</string>
@@ -46,6 +46,7 @@
     <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="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> හට දුරකථන ඇමතුම් සිදු කිරීමට ඉඩ නොදේ"</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>
diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml
index ef208d5..239af4e 100644
--- a/res/values-sk/strings.xml
+++ b/res/values-sk/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"Launcher3"</string>
+    <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"Pracovné"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"Aplikácia nie je nainštalovaná."</string>
@@ -46,6 +46,7 @@
     <string name="permdesc_read_settings" msgid="5833423719057558387">"Povoľuje aplikácii čítať nastavenia a odkazy na ploche."</string>
     <string name="permlab_write_settings" msgid="3574213698004620587">"zápis nastavení a odkazov plochy"</string>
     <string name="permdesc_write_settings" msgid="5440712911516509985">"Povoľuje aplikácii zmeniť nastavenia a odkazy na ploche."</string>
+    <string name="msg_no_phone_permission" msgid="9208659281529857371">"Aplikácia <xliff:g id="APP_NAME">%1$s</xliff:g> nemá povolenie uskutočňovať telefonické hovory"</string>
     <string name="gadget_error_text" msgid="6081085226050792095">"Problém s načítaním miniaplikácií"</string>
     <string name="gadget_setup_text" msgid="8274003207686040488">"Nastavenie"</string>
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Toto je systémová aplikácia a nedá sa odinštalovať."</string>
diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml
index cc25ff3..ad33be1 100644
--- a/res/values-sl/strings.xml
+++ b/res/values-sl/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"Zaganjalnik3"</string>
+    <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"Služba"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"Aplikacija ni nameščena."</string>
@@ -46,6 +46,7 @@
     <string name="permdesc_read_settings" msgid="5833423719057558387">"Aplikaciji dovoli branje nastavitev in bližnjic na začetnem zaslonu."</string>
     <string name="permlab_write_settings" msgid="3574213698004620587">"zapis nastavitev in bližnjic na začetnem zaslonu"</string>
     <string name="permdesc_write_settings" msgid="5440712911516509985">"Aplikaciji dovoli spreminjanje nastavitev in bližnjic na začetnem zaslonu."</string>
+    <string name="msg_no_phone_permission" msgid="9208659281529857371">"Aplikaciji <xliff:g id="APP_NAME">%1$s</xliff:g> ni dovoljeno opravljanje klicev"</string>
     <string name="gadget_error_text" msgid="6081085226050792095">"Težava pri nalaganju pripomočka"</string>
     <string name="gadget_setup_text" msgid="8274003207686040488">"Nastavitev"</string>
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"To je sistemska aplikacija in je ni mogoče odstraniti."</string>
diff --git a/res/values-sq-rAL/strings.xml b/res/values-sq-rAL/strings.xml
index f8bf12f..0648d3c 100644
--- a/res/values-sq-rAL/strings.xml
+++ b/res/values-sq-rAL/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"Nisësi3"</string>
+    <string name="app_name" msgid="649227358658669779">"Nisësi3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"Puna"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"Aplikacioni nuk është i instaluar."</string>
@@ -46,6 +46,7 @@
     <string name="permdesc_read_settings" msgid="5833423719057558387">"Lejon aplikacionin të lexojë cilësimet dhe shkurtoret në ekranin bazë."</string>
     <string name="permlab_write_settings" msgid="3574213698004620587">"shkruaj cilësimet dhe shkurtoret e ekranit bazë"</string>
     <string name="permdesc_write_settings" msgid="5440712911516509985">"Lejon aplikacionin të ndryshojë cilësimet dhe shkurtoret në ekranin bazë."</string>
+    <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> nuk lejohet të kryejë telefonata"</string>
     <string name="gadget_error_text" msgid="6081085226050792095">"Problem në ngarkimin e miniaplikacionit"</string>
     <string name="gadget_setup_text" msgid="8274003207686040488">"Konfiguro"</string>
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Ky është aplikacion sistemi dhe nuk mund të çinstalohet."</string>
diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml
index 413d108..2d6a4c0 100644
--- a/res/values-sr/strings.xml
+++ b/res/values-sr/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"Launcher3"</string>
+    <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"Work"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"Апликација није инсталирана."</string>
@@ -46,6 +46,7 @@
     <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="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> нема дозволу за упућивање телефонских позива"</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>
diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
index c52d205..82f8da8 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"Launcher3"</string>
+    <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"Arbete"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"Appen är inte installerad."</string>
@@ -46,6 +46,7 @@
     <string name="permdesc_read_settings" msgid="5833423719057558387">"Tillåter att appen läser inställningar och genvägar på startsidan."</string>
     <string name="permlab_write_settings" msgid="3574213698004620587">"skriva inställningar och genvägar för startsidan"</string>
     <string name="permdesc_write_settings" msgid="5440712911516509985">"Tillåter att appen ändrar inställningar och genvägar på startsidan."</string>
+    <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> har inte behörighet att ringa samtal"</string>
     <string name="gadget_error_text" msgid="6081085226050792095">"Det gick inte att läsa in widgeten"</string>
     <string name="gadget_setup_text" msgid="8274003207686040488">"Konfiguration"</string>
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Det här är en systemapp som inte kan avinstalleras."</string>
diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml
index 195900b..2633a2f 100644
--- a/res/values-sw/strings.xml
+++ b/res/values-sw/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"Kizindua3"</string>
+    <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"Kazini"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"Programu haijasakinishwa."</string>
@@ -46,6 +46,7 @@
     <string name="permdesc_read_settings" msgid="5833423719057558387">"Huruhusu programu kusoma mipangilio na njia za mikato zilizo katika skirini ya Mwanzo."</string>
     <string name="permlab_write_settings" msgid="3574213698004620587">"andika mipangilio ya skrini ya Mwanzo na njia za mkato"</string>
     <string name="permdesc_write_settings" msgid="5440712911516509985">"Huruhusu programu kubadilisha mipangilio na njia za mkato katika skrini ya Mwanzo."</string>
+    <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> hairuhusiwi kupiga simu"</string>
     <string name="gadget_error_text" msgid="6081085226050792095">"Tatizo la kupakia wijeti"</string>
     <string name="gadget_setup_text" msgid="8274003207686040488">"Sanidi"</string>
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Hii ni programu ya mfumo na haiwezi kuondolewa."</string>
diff --git a/res/values-ta-rIN/strings.xml b/res/values-ta-rIN/strings.xml
index e1b6b38..1424cae 100644
--- a/res/values-ta-rIN/strings.xml
+++ b/res/values-ta-rIN/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"லாஞ்சர்3"</string>
+    <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"பணியிடம்"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"பயன்பாடு நிறுவப்படவில்லை."</string>
@@ -46,6 +46,7 @@
     <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="msg_no_phone_permission" msgid="9208659281529857371">"ஃபோன் அழைப்புகள் செய்ய, <xliff:g id="APP_NAME">%1$s</xliff:g> அனுமதிக்கப்படவில்லை"</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>
diff --git a/res/values-te-rIN/strings.xml b/res/values-te-rIN/strings.xml
index 4f5b3c0..7c950e4 100644
--- a/res/values-te-rIN/strings.xml
+++ b/res/values-te-rIN/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"లాంచర్3"</string>
+    <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"కార్యాలయం"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"అనువర్తనం ఇన్‌స్టాల్ చేయబడలేదు."</string>
@@ -46,6 +46,7 @@
     <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="msg_no_phone_permission" msgid="9208659281529857371">"ఫోన్ కాల్‌లను చేసేందుకు <xliff:g id="APP_NAME">%1$s</xliff:g>కి అనుమతి లేదు"</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>
diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml
index 2bc32d9..3924463 100644
--- a/res/values-th/strings.xml
+++ b/res/values-th/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"Launcher3"</string>
+    <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"งาน"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"ไม่ได้ติดตั้งแอป"</string>
@@ -46,6 +46,7 @@
     <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="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> ไม่ได้รับอนุญาตให้โทรออก"</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>
diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml
index 828c95a..a88f3d2 100644
--- a/res/values-tl/strings.xml
+++ b/res/values-tl/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"Launcher3"</string>
+    <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"Trabaho"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"Hindi naka-install ang app."</string>
@@ -46,6 +46,7 @@
     <string name="permdesc_read_settings" msgid="5833423719057558387">"Pinapayagan ang app na basahin ang mga setting at shortcut sa Home."</string>
     <string name="permlab_write_settings" msgid="3574213698004620587">"magsulat ng mga setting at shortcut ng Home"</string>
     <string name="permdesc_write_settings" msgid="5440712911516509985">"Pinapayagan ang app na baguhin ang mga setting at shortcut sa Home."</string>
+    <string name="msg_no_phone_permission" msgid="9208659281529857371">"Hindi pinahihintulutang tumawag ang <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="gadget_error_text" msgid="6081085226050792095">"Problema sa pag-load ng widget"</string>
     <string name="gadget_setup_text" msgid="8274003207686040488">"I-setup"</string>
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Isa itong app ng system at hindi maaaring i-uninstall."</string>
diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml
index eec149e..39e0c6e 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"Launcher3"</string>
+    <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"İş"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"Uygulama yüklü değil."</string>
@@ -46,6 +46,7 @@
     <string name="permdesc_read_settings" msgid="5833423719057558387">"Uygulamaya, Ana ekrandaki ayarları ve kısayolları okuma izni verir."</string>
     <string name="permlab_write_settings" msgid="3574213698004620587">"Ana ekran ayarlarını ve kısayollarını yaz"</string>
     <string name="permdesc_write_settings" msgid="5440712911516509985">"Uygulamaya, Ana ekrandaki ayarları ve kısayolları değiştirme izni verir."</string>
+    <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> uygulamasının telefon etmesine izin verilmiyor"</string>
     <string name="gadget_error_text" msgid="6081085226050792095">"Widget yüklenirken sorun oluştu"</string>
     <string name="gadget_setup_text" msgid="8274003207686040488">"Kurulum"</string>
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Bu bir sistem uygulamasıdır ve yüklemesi kaldırılamaz."</string>
diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml
index c6c1a6d..ab5385f 100644
--- a/res/values-uk/strings.xml
+++ b/res/values-uk/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"Launcher3"</string>
+    <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"Робоча папка"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"Додаток видалено."</string>
@@ -46,6 +46,7 @@
     <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="msg_no_phone_permission" msgid="9208659281529857371">"Додаток <xliff:g id="APP_NAME">%1$s</xliff:g> не має дозволу телефонувати"</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>
diff --git a/res/values-ur-rPK/strings.xml b/res/values-ur-rPK/strings.xml
index 9c127b3..abce1ff 100644
--- a/res/values-ur-rPK/strings.xml
+++ b/res/values-ur-rPK/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"Launcher3"</string>
+    <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"دفتری"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"ایپ انسٹال نہیں ہے۔"</string>
@@ -46,6 +46,7 @@
     <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="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> کو فون کالیں کرنے کی اجازت نہیں ہے"</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>
diff --git a/res/values-uz-rUZ/strings.xml b/res/values-uz-rUZ/strings.xml
index 5f78b08..70b15cb 100644
--- a/res/values-uz-rUZ/strings.xml
+++ b/res/values-uz-rUZ/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"Ishga tushirgich3"</string>
+    <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"Ishga oid"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"Ilova o‘rnatilmadi."</string>
@@ -46,6 +46,7 @@
     <string name="permdesc_read_settings" msgid="5833423719057558387">"Ilovaga \"Uy\" ekranidagi yorliqlar va sozlamalarni o‘qish uchun ruxsat beradi."</string>
     <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="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> ilovasiga qo‘ng‘iroqlarni amalga oshirishga ruxsat berilmagan"</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>
diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml
index 248a8e7..8ffc97f 100644
--- a/res/values-vi/strings.xml
+++ b/res/values-vi/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"Launcher3"</string>
+    <string name="app_name" msgid="649227358658669779">"Trình chạy 3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"Work"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"Ứng dụng chưa được cài đặt."</string>
@@ -46,6 +46,7 @@
     <string name="permdesc_read_settings" msgid="5833423719057558387">"Cho phép ứng dụng đọc cài đặt và lối tắt trên Màn hình chính."</string>
     <string name="permlab_write_settings" msgid="3574213698004620587">"ghi cài đặt và lối tắt trên Màn hình chính"</string>
     <string name="permdesc_write_settings" msgid="5440712911516509985">"Cho phép ứng dụng thay đổi cài đặt và lối tắt trên Màn hình chính."</string>
+    <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> không được phép thực hiện cuộc gọi điện thoại"</string>
     <string name="gadget_error_text" msgid="6081085226050792095">"Sự cố khi tải tiện ích con"</string>
     <string name="gadget_setup_text" msgid="8274003207686040488">"Thiết lập"</string>
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Đây là ứng dụng hệ thống và không thể gỡ cài đặt."</string>
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index 18a5d3d..b76991b 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"Launcher3"</string>
+    <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"Work"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"未安装该应用。"</string>
@@ -46,6 +46,7 @@
     <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="msg_no_phone_permission" msgid="9208659281529857371">"不允许使用“<xliff:g id="APP_NAME">%1$s</xliff:g>”拨打电话"</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>
diff --git a/res/values-zh-rHK/strings.xml b/res/values-zh-rHK/strings.xml
index c114562..12bdfd6 100644
--- a/res/values-zh-rHK/strings.xml
+++ b/res/values-zh-rHK/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"Launcher3"</string>
+    <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"工作"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"尚未安裝應用程式。"</string>
@@ -46,6 +46,7 @@
     <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="msg_no_phone_permission" msgid="9208659281529857371">"不允許 <xliff:g id="APP_NAME">%1$s</xliff:g> 撥打電話"</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>
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index 59fa489..41d199a 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"Launcher3"</string>
+    <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"公司"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"應用程式未安裝。"</string>
@@ -46,6 +46,7 @@
     <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="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> 無法撥打電話"</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>
diff --git a/res/values-zu/strings.xml b/res/values-zu/strings.xml
index 93863d7..14c6819 100644
--- a/res/values-zu/strings.xml
+++ b/res/values-zu/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="5181331383435256801">"Isiqalisi3"</string>
+    <string name="app_name" msgid="649227358658669779">"Isiqalisi3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"Umsebenzi"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"Uhlelo lokusebenza alufakiwe."</string>
@@ -46,6 +46,7 @@
     <string name="permdesc_read_settings" msgid="5833423719057558387">"Ivumela uhlelo lokusebenza ukuthi lifunde izilungiselelo nezinqamuleli ekhaya."</string>
     <string name="permlab_write_settings" msgid="3574213698004620587">"bhala izilungiselelo zokuthi Ikhaya nezinqamuleli"</string>
     <string name="permdesc_write_settings" msgid="5440712911516509985">"Ivumela uhlelo lokusebenza ukuthi lushintshe izilungiselelo nezinqamuleli Ekhaya."</string>
+    <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> ayivunyelwe ukwenza amakholi wefoni"</string>
     <string name="gadget_error_text" msgid="6081085226050792095">"Inkinga yokulayisha iwijethi"</string>
     <string name="gadget_setup_text" msgid="8274003207686040488">"Ukumisa"</string>
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Lolu uhlelo lokusebenza lwesistimu futhi alikwazi ukukhishwa."</string>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index c30ee1d..90083c0 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -17,11 +17,15 @@
 <resources>
 <!-- Dynamic Grid -->
     <dimen name="dynamic_grid_edge_margin">6dp</dimen>
-    <dimen name="dynamic_grid_search_bar_max_width">500dp</dimen>
-    <dimen name="dynamic_grid_search_bar_height">56dp</dimen>
-    <!-- We want 32dp extra for the tall search bar, but 10dp comes from unwanted padding between
-         the search bar and workspace. -->
-    <dimen name="dynamic_grid_search_bar_height_tall">78dp</dimen>
+    <dimen name="dynamic_grid_search_bar_height">48dp</dimen>
+    <!-- We want 32dp extra for the tall search bar. -->
+    <dimen name="dynamic_grid_search_bar_height_tall">80dp</dimen>
+    <dimen name="qsb_internal_padding_top">8dp</dimen>
+    <dimen name="qsb_internal_padding_bottom">8dp</dimen>
+    <dimen name="dynamic_grid_search_bar_bottom_padding">4dp</dimen>
+    <!-- Reduce the padding between the search bar and workspace when the search bar is tall -->
+    <dimen name="dynamic_grid_search_bar_bottom_padding_short">-6dp</dimen>
+    <dimen name="dynamic_grid_search_bar_bottom_padding_tablet">16dp</dimen>
     <dimen name="dynamic_grid_page_indicator_height">20dp</dimen>
     <dimen name="dynamic_grid_icon_drawable_padding">4dp</dimen>
     <dimen name="dynamic_grid_workspace_page_spacing">8dp</dimen>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index a17437e..ecbdcc2 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -31,7 +31,7 @@
     <string name="receive_first_load_broadcast_permission" translatable="false">com.android.launcher3.permission.RECEIVE_FIRST_LOAD_BROADCAST</string>
 
     <!-- Application name -->
-    <string name="application_name">Launcher3</string>
+    <string name="app_name">Launcher3</string>
     <!-- Default folder name -->
     <string name="folder_name"></string>
     <!-- Work folder name -->
@@ -103,6 +103,9 @@
     <string name="permdesc_write_settings">Allows the app to change the settings and
         shortcuts in Home.</string>
 
+    <!-- Toast shown on clicking a direct call shortcut. [CHAR_LIMIT=80] -->
+    <string name="msg_no_phone_permission"><xliff:g id="app_name" example="Launcher3">%1$s</xliff:g> is not allowed to make phone calls</string>
+
     <!-- Widgets: -->
     <skip />    
 
diff --git a/src/com/android/launcher3/AnotherWindowDropTarget.java b/src/com/android/launcher3/AnotherWindowDropTarget.java
index eaac6be..0e18874 100644
--- a/src/com/android/launcher3/AnotherWindowDropTarget.java
+++ b/src/com/android/launcher3/AnotherWindowDropTarget.java
@@ -61,13 +61,4 @@
     // These methods are implemented in Views
     @Override
     public void getHitRectRelativeToDragLayer(Rect outRect) {}
-
-    @Override
-    public void getLocationInDragLayer(int[] loc) {}
-
-    @Override
-    public int getLeft() { return 0; }
-
-    @Override
-    public int getTop() { return 0; }
 }
diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java
index 10db459..a3b92dc 100644
--- a/src/com/android/launcher3/BubbleTextView.java
+++ b/src/com/android/launcher3/BubbleTextView.java
@@ -252,6 +252,9 @@
             FastBitmapDrawable d = (FastBitmapDrawable) mIcon;
             if (isPressed() || mStayPressed) {
                 d.animateState(FastBitmapDrawable.State.PRESSED);
+            } else if (getTag() instanceof ShortcutInfo
+                    && ((ShortcutInfo) getTag()).isDisabled != 0) {
+                d.animateState(FastBitmapDrawable.State.DISABLED);
             } else {
                 d.animateState(FastBitmapDrawable.State.NORMAL);
             }
diff --git a/src/com/android/launcher3/ButtonDropTarget.java b/src/com/android/launcher3/ButtonDropTarget.java
index 4b94a1a..d882683 100644
--- a/src/com/android/launcher3/ButtonDropTarget.java
+++ b/src/com/android/launcher3/ButtonDropTarget.java
@@ -302,11 +302,6 @@
         return to;
     }
 
-    @Override
-    public void getLocationInDragLayer(int[] loc) {
-        mLauncher.getDragLayer().getLocationInDragLayer(this, loc);
-    }
-
     public void enableAccessibleDrag(boolean enable) {
         setOnClickListener(enable ? this : null);
     }
diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java
index 92e4043..a28b835 100644
--- a/src/com/android/launcher3/CellLayout.java
+++ b/src/com/android/launcher3/CellLayout.java
@@ -69,7 +69,8 @@
     public static final int WORKSPACE_ACCESSIBILITY_DRAG = 2;
     public static final int FOLDER_ACCESSIBILITY_DRAG = 1;
 
-    static final String TAG = "CellLayout";
+    private static final String TAG = "CellLayout";
+    private static final boolean LOGD = false;
 
     private Launcher mLauncher;
     @Thunk int mCellWidth;
@@ -152,9 +153,6 @@
     private static final boolean DESTRUCTIVE_REORDER = false;
     private static final boolean DEBUG_VISUALIZE_OCCUPIED = false;
 
-    static final int LANDSCAPE = 0;
-    static final int PORTRAIT = 1;
-
     private static final float REORDER_PREVIEW_MAGNITUDE = 0.12f;
     private static final int REORDER_ANIMATION_DURATION = 150;
     @Thunk float mReorderPreviewAnimationMagnitude;
@@ -244,9 +242,7 @@
                     // If an animation is started and then stopped very quickly, we can still
                     // get spurious updates we've cleared the tag. Guard against this.
                     if (outline == null) {
-                        @SuppressWarnings("all") // suppress dead code warning
-                        final boolean debug = false;
-                        if (debug) {
+                        if (LOGD) {
                             Object val = animation.getAnimatedValue();
                             Log.d(TAG, "anim " + thisIndex + " update: " + val +
                                      ", isStopped " + anim.isStopped());
@@ -404,10 +400,6 @@
         mIsDragTarget = false;
     }
 
-    public boolean isDragTarget() {
-        return mIsDragTarget;
-    }
-
     void setIsDragOverlapping(boolean isDragOverlapping) {
         if (mIsDragOverlapping != isDragOverlapping) {
             mIsDragOverlapping = isDragOverlapping;
@@ -450,10 +442,6 @@
                 (ParcelableSparseArray) parcelable : new ParcelableSparseArray();
     }
 
-    public boolean getIsDragOverlapping() {
-        return mIsDragOverlapping;
-    }
-
     @Override
     protected void onDraw(Canvas canvas) {
         if (!mIsDragTarget) {
@@ -653,6 +641,9 @@
             if (lp.cellVSpan < 0) lp.cellVSpan = mCountY;
 
             child.setId(childId);
+            if (LOGD) {
+                Log.d(TAG, "Adding view to ShortcutsAndWidgetsContainer: " + child);
+            }
             mShortcutsAndWidgets.addView(child, index, lp);
 
             if (markCells) markCellsAsOccupiedForView(child);
@@ -896,9 +887,14 @@
 
     @Override
     protected void onLayout(boolean changed, int l, int t, int r, int b) {
-        int offset = getMeasuredWidth() - getPaddingLeft() - getPaddingRight() -
-                (mCountX * mCellWidth);
-        int left = getPaddingLeft() + (int) Math.ceil(offset / 2f);
+        boolean isFullscreen = mShortcutsAndWidgets.getChildCount() > 0 &&
+                ((LayoutParams) mShortcutsAndWidgets.getChildAt(0).getLayoutParams()).isFullscreen;
+        int left = getPaddingLeft();
+        if (!isFullscreen) {
+            int offset = getMeasuredWidth() - getPaddingLeft() - getPaddingRight() -
+                    (mCountX * mCellWidth);
+            left += (int) Math.ceil(offset / 2f);
+        }
         int top = getPaddingTop();
 
         mTouchFeedbackView.layout(left, top,
@@ -1311,9 +1307,7 @@
      * @param spanX Horizontal span of the object.
      * @param spanY Vertical span of the object.
      * @param direction The favored direction in which the views should move from x, y
-     * @param exactDirectionOnly If this parameter is true, then only solutions where the direction
-     *        matches exactly. Otherwise we find the best matching direction.
-     * @param occoupied The array which represents which cells in the CellLayout are occupied
+     * @param occupied The array which represents which cells in the CellLayout are occupied
      * @param blockOccupied The array which represents which cells in the specified block (cellX,
      *        cellY, spanX, spanY) are occupied. This is used when try to move a group of views.
      * @param result Array in which to place the result, or null (in which case a new array will
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index 4a489de..d2ca8f6 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -90,7 +90,7 @@
     public int hotseatCellWidthPx;
     public int hotseatCellHeightPx;
     public int hotseatIconSizePx;
-    private int hotseatBarHeightNormalPx, hotseatBarHeightShortPx;
+    private int normalHotseatBarHeightPx, shortHotseatBarHeightPx;
     private int hotseatBarHeightPx; // One of the above.
 
     // All apps
@@ -101,10 +101,12 @@
     public final int allAppsIconTextSizePx;
 
     // QSB
-    private int searchBarSpaceWidthPx;
-    private int searchBarSpaceHeightNormalPx, searchBarSpaceHeightTallPx;
+    private int searchBarWidgetInternalPaddingTop, searchBarWidgetInternalPaddingBottom;
+    private int searchBarTopPaddingPx;
+    private int normalSearchBarBottomPaddingPx, tallSearchBarBottomPaddingPx;
+    private int searchBarBottomPaddingPx; // One of the above.
+    private int normalSearchBarSpaceHeightPx, tallSearchBarSpaceHeightPx;
     private int searchBarSpaceHeightPx; // One of the above.
-    private int searchBarHeight = LauncherCallbacks.SEARCH_BAR_HEIGHT_NORMAL;
 
     public DeviceProfile(Context context, InvariantDeviceProfile inv,
             Point minSize, Point maxSize,
@@ -206,12 +208,26 @@
         hotseatIconSizePx = (int) (Utilities.pxFromDp(inv.hotseatIconSize, dm) * scale);
 
         // Search Bar
-        searchBarSpaceWidthPx = Math.min(widthPx,
-                res.getDimensionPixelSize(R.dimen.dynamic_grid_search_bar_max_width));
-        searchBarSpaceHeightNormalPx = getSearchBarTopOffset()
-                + res.getDimensionPixelSize(R.dimen.dynamic_grid_search_bar_height);
-        searchBarSpaceHeightTallPx = getSearchBarTopOffset()
-                + res.getDimensionPixelSize(R.dimen.dynamic_grid_search_bar_height_tall);
+        normalSearchBarSpaceHeightPx = res.getDimensionPixelSize(
+                R.dimen.dynamic_grid_search_bar_height);
+        tallSearchBarSpaceHeightPx = res.getDimensionPixelSize(
+                R.dimen.dynamic_grid_search_bar_height_tall);
+        searchBarWidgetInternalPaddingTop = res.getDimensionPixelSize(
+                R.dimen.qsb_internal_padding_top);
+        searchBarWidgetInternalPaddingBottom = res.getDimensionPixelSize(
+                R.dimen.qsb_internal_padding_bottom);
+        if (isTablet && !isVerticalBarLayout()) {
+            searchBarTopPaddingPx = searchBarWidgetInternalPaddingTop;
+            normalSearchBarBottomPaddingPx = searchBarWidgetInternalPaddingBottom +
+                    res.getDimensionPixelSize(R.dimen.dynamic_grid_search_bar_bottom_padding_tablet);
+            tallSearchBarBottomPaddingPx = normalSearchBarBottomPaddingPx;
+        } else {
+            searchBarTopPaddingPx = searchBarWidgetInternalPaddingTop;
+            normalSearchBarBottomPaddingPx = searchBarWidgetInternalPaddingBottom +
+                    res.getDimensionPixelSize(R.dimen.dynamic_grid_search_bar_bottom_padding);
+            tallSearchBarBottomPaddingPx = searchBarWidgetInternalPaddingBottom +
+                    res.getDimensionPixelSize(R.dimen.dynamic_grid_search_bar_bottom_padding_short);
+        }
 
         // Calculate the actual text height
         Paint textPaint = new Paint();
@@ -223,13 +239,14 @@
         dragViewScale = (iconSizePx + scaleDps) / iconSizePx;
 
         // Hotseat
-        hotseatBarHeightNormalPx = iconSizePx + 4 * edgeMarginPx;
-        hotseatBarHeightShortPx = iconSizePx + 2 * edgeMarginPx;
+        normalHotseatBarHeightPx = iconSizePx + 4 * edgeMarginPx;
+        shortHotseatBarHeightPx = iconSizePx + 2 * edgeMarginPx;
         hotseatCellWidthPx = iconSizePx;
         hotseatCellHeightPx = iconSizePx;
 
         // Folder
-        folderCellWidthPx = cellWidthPx + 3 * edgeMarginPx;
+        folderCellWidthPx = Math.min(cellWidthPx + 6 * edgeMarginPx,
+                (availableWidthPx - 4 * edgeMarginPx) / inv.numFolderColumns);
         folderCellHeightPx = cellHeightPx + edgeMarginPx;
         folderBackgroundOffset = -edgeMarginPx;
         folderIconSizePx = iconSizePx + 2 * -folderBackgroundOffset;
@@ -251,13 +268,20 @@
         allAppsNumPredictiveCols = numPredictiveAppCols;
     }
 
-    /** Returns the search bar top offset */
-    private int getSearchBarTopOffset() {
-        if (isTablet && !isVerticalBarLayout()) {
-            return 4 * edgeMarginPx;
-        } else {
-            return 2 * edgeMarginPx;
+    /** Returns the amount of extra space to allocate to the search bar for vertical padding. */
+    private int getSearchBarTotalVerticalPadding() {
+        return searchBarTopPaddingPx + searchBarBottomPaddingPx;
+    }
+
+    /** Returns the width and height of the search bar, ignoring any padding. */
+    public Point getSearchBarDimensForWidgetOpts(Resources res) {
+        Rect searchBarBounds = getSearchBarBounds(Utilities.isRtl(res));
+        if (isVerticalBarLayout()) {
+            return new Point(searchBarBounds.width(), searchBarBounds.height());
         }
+        int widgetInternalPadding = searchBarWidgetInternalPaddingTop +
+                searchBarWidgetInternalPaddingBottom;
+        return new Point(searchBarBounds.width(), searchBarSpaceHeightPx + widgetInternalPadding);
     }
 
     /** Returns the search bar bounds in the current orientation */
@@ -265,13 +289,14 @@
         Rect bounds = new Rect();
         if (isVerticalBarLayout()) {
             if (isLayoutRtl) {
-                bounds.set(availableWidthPx - searchBarSpaceHeightNormalPx, edgeMarginPx,
+                bounds.set(availableWidthPx - normalSearchBarSpaceHeightPx, edgeMarginPx,
                         availableWidthPx, availableHeightPx - edgeMarginPx);
             } else {
-                bounds.set(0, edgeMarginPx, searchBarSpaceHeightNormalPx,
+                bounds.set(0, edgeMarginPx, normalSearchBarSpaceHeightPx,
                         availableHeightPx - edgeMarginPx);
             }
         } else {
+            int boundsBottom = searchBarSpaceHeightPx + getSearchBarTotalVerticalPadding();
             if (isTablet) {
                 // Pad the left and right of the workspace to ensure consistent spacing
                 // between all icons
@@ -280,14 +305,13 @@
                 //      that into account here too.
                 int gap = (int) ((width - 2 * edgeMarginPx -
                         (inv.numColumns * cellWidthPx)) / (2 * (inv.numColumns + 1)));
-                bounds.set(edgeMarginPx + gap, getSearchBarTopOffset(),
-                        availableWidthPx - (edgeMarginPx + gap),
-                        searchBarSpaceHeightPx);
+                bounds.set(edgeMarginPx + gap, 0,
+                        availableWidthPx - (edgeMarginPx + gap), boundsBottom);
             } else {
                 bounds.set(desiredWorkspaceLeftRightMarginPx - defaultWidgetPadding.left,
-                        getSearchBarTopOffset(),
+                        0,
                         availableWidthPx - (desiredWorkspaceLeftRightMarginPx -
-                        defaultWidgetPadding.right), searchBarSpaceHeightPx);
+                        defaultWidgetPadding.right), boundsBottom);
             }
         }
         return bounds;
@@ -312,21 +336,21 @@
         if (isVerticalBarLayout()) {
             // Pad the left and right of the workspace with search/hotseat bar sizes
             if (isLayoutRtl) {
-                padding.set(hotseatBarHeightNormalPx, edgeMarginPx,
+                padding.set(normalHotseatBarHeightPx, edgeMarginPx,
                         searchBarBounds.width(), edgeMarginPx);
             } else {
                 padding.set(searchBarBounds.width(), edgeMarginPx,
-                        hotseatBarHeightNormalPx, edgeMarginPx);
+                        normalHotseatBarHeightPx, edgeMarginPx);
             }
         } else {
+            int paddingTop = searchBarBounds.bottom;
+            int paddingBottom = hotseatBarHeightPx + pageIndicatorHeightPx;
             if (isTablet) {
                 // Pad the left and right of the workspace to ensure consistent spacing
                 // between all icons
                 float gapScale = 1f + (dragViewScale - 1f) / 2f;
                 int width = getCurrentWidth();
                 int height = getCurrentHeight();
-                int paddingTop = searchBarBounds.bottom;
-                int paddingBottom = hotseatBarHeightPx + pageIndicatorHeightPx;
                 // The amount of screen space available for left/right padding.
                 int availablePaddingX = Math.max(0, width - (int) ((inv.numColumns * cellWidthPx) +
                         ((inv.numColumns - 1) * gapScale * cellWidthPx)));
@@ -339,9 +363,9 @@
             } else {
                 // Pad the top and bottom of the workspace with search/hotseat bar sizes
                 padding.set(desiredWorkspaceLeftRightMarginPx - defaultWidgetPadding.left,
-                        searchBarBounds.bottom,
+                        paddingTop,
                         desiredWorkspaceLeftRightMarginPx - defaultWidgetPadding.right,
-                        hotseatBarHeightPx + pageIndicatorHeightPx);
+                        paddingBottom);
             }
         }
         return padding;
@@ -407,22 +431,30 @@
         return visibleChildren;
     }
 
+    // TODO(twickham): b/25154513
+    public void setSearchBarHeight(int searchBarHeight) {
+        if (searchBarHeight == LauncherCallbacks.SEARCH_BAR_HEIGHT_TALL) {
+            hotseatBarHeightPx = shortHotseatBarHeightPx;
+            searchBarSpaceHeightPx = tallSearchBarSpaceHeightPx;
+            searchBarBottomPaddingPx = tallSearchBarBottomPaddingPx;
+        } else {
+            hotseatBarHeightPx = normalHotseatBarHeightPx;
+            searchBarSpaceHeightPx = normalSearchBarSpaceHeightPx;
+            searchBarBottomPaddingPx = normalSearchBarBottomPaddingPx;
+        }
+    }
+
     public void layout(Launcher launcher) {
         FrameLayout.LayoutParams lp;
         boolean hasVerticalBarLayout = isVerticalBarLayout();
         final boolean isLayoutRtl = Utilities.isRtl(launcher.getResources());
 
         // Layout the search bar space
-        searchBarHeight = launcher.getSearchBarHeight();
-        if (searchBarHeight == LauncherCallbacks.SEARCH_BAR_HEIGHT_TALL) {
-            hotseatBarHeightPx = hotseatBarHeightShortPx;
-            searchBarSpaceHeightPx = searchBarSpaceHeightTallPx;
-        } else {
-            hotseatBarHeightPx = hotseatBarHeightNormalPx;
-            searchBarSpaceHeightPx = searchBarSpaceHeightNormalPx;
-        }
+        Rect searchBarBounds = getSearchBarBounds(isLayoutRtl);
         View searchBar = launcher.getSearchDropTargetBar();
         lp = getDropTargetBarLayoutParams(hasVerticalBarLayout, searchBar, Gravity.TOP);
+        lp.width = searchBarBounds.width();
+        lp.height = searchBarBounds.height();
         searchBar.setLayoutParams(lp);
 
         // Layout the app info bar space
@@ -454,7 +486,7 @@
             // Vertical hotseat -- The hotseat is fixed in the layout to be on the right of the
             //                     screen regardless of RTL
             lp.gravity = Gravity.RIGHT;
-            lp.width = hotseatBarHeightNormalPx;
+            lp.width = normalHotseatBarHeightPx;
             lp.height = LayoutParams.MATCH_PARENT;
             hotseat.findViewById(R.id.layout).setPadding(0, 2 * edgeMarginPx, 0, 2 * edgeMarginPx);
         } else if (isTablet) {
@@ -541,7 +573,7 @@
             // Vertical drop target bar space -- The drop target bar is fixed in the layout to be on
             //                                   the left of the screen regardless of RTL
             lp.gravity = Gravity.LEFT;
-            lp.width = searchBarSpaceHeightPx;
+            lp.width = normalSearchBarSpaceHeightPx;
 
             LinearLayout targets = (LinearLayout) dropTargetBar.findViewById(R.id.drag_target_bar);
             targets.setOrientation(LinearLayout.VERTICAL);
@@ -550,11 +582,8 @@
             targetsLp.height = LayoutParams.WRAP_CONTENT;
         } else {
             // Horizontal drop target bar space
-            lp.gravity = verticalGravity;
+            lp.gravity = verticalGravity | Gravity.CENTER_HORIZONTAL;
             lp.height = searchBarSpaceHeightPx;
-
-            LinearLayout targets = (LinearLayout) dropTargetBar.findViewById(R.id.drag_target_bar);
-            targets.getLayoutParams().width = searchBarSpaceWidthPx;
         }
         return lp;
     }
diff --git a/src/com/android/launcher3/DropTarget.java b/src/com/android/launcher3/DropTarget.java
index bab46d9..90b8f1c 100644
--- a/src/com/android/launcher3/DropTarget.java
+++ b/src/com/android/launcher3/DropTarget.java
@@ -29,9 +29,7 @@
  */
 public interface DropTarget {
 
-    public static final String TAG = "DropTarget";
-
-    public static class DragObject {
+    class DragObject {
         public int x = -1;
         public int y = -1;
 
@@ -154,7 +152,4 @@
 
     // These methods are implemented in Views
     void getHitRectRelativeToDragLayer(Rect outRect);
-    void getLocationInDragLayer(int[] loc);
-    int getLeft();
-    int getTop();
 }
diff --git a/src/com/android/launcher3/FastBitmapDrawable.java b/src/com/android/launcher3/FastBitmapDrawable.java
index 30bc7ea..d7f1d86 100644
--- a/src/com/android/launcher3/FastBitmapDrawable.java
+++ b/src/com/android/launcher3/FastBitmapDrawable.java
@@ -42,8 +42,8 @@
 
         NORMAL                      (0f, 0f, 1f, new DecelerateInterpolator()),
         PRESSED                     (0f, 100f / 255f, 1f, CLICK_FEEDBACK_INTERPOLATOR),
-        FAST_SCROLL_HIGHLIGHTED     (0f, 0f, 1.1f, new DecelerateInterpolator()),
-        FAST_SCROLL_UNHIGHLIGHTED   (0.8f, 0.35f, 1f, new DecelerateInterpolator()),
+        FAST_SCROLL_HIGHLIGHTED     (0f, 0f, 1.15f, new DecelerateInterpolator()),
+        FAST_SCROLL_UNHIGHLIGHTED   (0f, 0f, 1f, new DecelerateInterpolator()),
         DISABLED                    (1f, 0.5f, 1f, new DecelerateInterpolator());
 
         public final float desaturation;
diff --git a/src/com/android/launcher3/FocusHelper.java b/src/com/android/launcher3/FocusHelper.java
index 099194c..d7f05ed 100644
--- a/src/com/android/launcher3/FocusHelper.java
+++ b/src/com/android/launcher3/FocusHelper.java
@@ -143,7 +143,8 @@
                     newParent = getCellLayoutChildrenForIndex(pagedView, pageIndex + 1);
                     if (newParent != null) {
                         pagedView.snapToPage(pageIndex + 1);
-                        child = FocusLogic.getAdjacentChildInNextPage(newParent, v, newIconIndex);
+                        child = FocusLogic.getAdjacentChildInNextFolderPage(
+                                newParent, v, newIconIndex);
                     }
                     break;
                 case FocusLogic.CURRENT_PAGE_FIRST_ITEM:
@@ -365,9 +366,7 @@
                 }
                 int row = ((CellLayout.LayoutParams) v.getLayoutParams()).cellY;
                 parent = getCellLayoutChildrenForIndex(workspace, newPageIndex);
-                workspace.snapToPage(newPageIndex);
                 if (parent != null) {
-                    workspace.snapToPage(newPageIndex);
                     iconLayout = (CellLayout) parent.getParent();
                     matrix = FocusLogic.createSparseMatrix(iconLayout,
                         iconLayout.getCountX(), row);
@@ -380,17 +379,14 @@
             case FocusLogic.PREVIOUS_PAGE_FIRST_ITEM:
                 parent = getCellLayoutChildrenForIndex(workspace, pageIndex - 1);
                 newIcon = parent.getChildAt(0);
-                workspace.snapToPage(pageIndex - 1);
                 break;
             case FocusLogic.PREVIOUS_PAGE_LAST_ITEM:
                 parent = getCellLayoutChildrenForIndex(workspace, pageIndex - 1);
                 newIcon = parent.getChildAt(parent.getChildCount() - 1);
-                workspace.snapToPage(pageIndex - 1);
                 break;
             case FocusLogic.NEXT_PAGE_FIRST_ITEM:
                 parent = getCellLayoutChildrenForIndex(workspace, pageIndex + 1);
                 newIcon = parent.getChildAt(0);
-                workspace.snapToPage(pageIndex + 1);
                 break;
             case FocusLogic.NEXT_PAGE_LEFT_COLUMN:
             case FocusLogic.PREVIOUS_PAGE_LEFT_COLUMN:
@@ -398,11 +394,9 @@
                 if (newIconIndex == FocusLogic.PREVIOUS_PAGE_LEFT_COLUMN) {
                     newPageIndex = pageIndex - 1;
                 }
-                workspace.snapToPage(newPageIndex);
                 row = ((CellLayout.LayoutParams) v.getLayoutParams()).cellY;
                 parent = getCellLayoutChildrenForIndex(workspace, newPageIndex);
                 if (parent != null) {
-                    workspace.snapToPage(newPageIndex);
                     iconLayout = (CellLayout) parent.getParent();
                     matrix = FocusLogic.createSparseMatrix(iconLayout, -1, row);
                     newIconIndex = FocusLogic.handleKeyEvent(keyCode, countX + 1, countY,
diff --git a/src/com/android/launcher3/Folder.java b/src/com/android/launcher3/Folder.java
index 142932f..27572e3 100644
--- a/src/com/android/launcher3/Folder.java
+++ b/src/com/android/launcher3/Folder.java
@@ -210,8 +210,26 @@
         });
         mFolderName.setOnFocusChangeListener(this);
 
-        // We disable action mode for now since it messes up the view on phones
-        mFolderName.setCustomSelectionActionModeCallback(mActionModeCallback);
+        if (!Utilities.ATLEAST_MARSHMALLOW) {
+            // We disable action mode in older OSes where floating selection menu is not yet
+            // available.
+            mFolderName.setCustomSelectionActionModeCallback(new ActionMode.Callback() {
+                public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
+                    return false;
+                }
+
+                public boolean onCreateActionMode(ActionMode mode, Menu menu) {
+                    return false;
+                }
+
+                public void onDestroyActionMode(ActionMode mode) {
+                }
+
+                public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
+                    return false;
+                }
+            });
+        }
         mFolderName.setOnEditorActionListener(this);
         mFolderName.setSelectAllOnFocus(true);
         mFolderName.setInputType(mFolderName.getInputType() |
@@ -226,23 +244,6 @@
         mFooterHeight = mFooter.getMeasuredHeight();
     }
 
-    private ActionMode.Callback mActionModeCallback = new ActionMode.Callback() {
-        public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
-            return false;
-        }
-
-        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
-            return false;
-        }
-
-        public void onDestroyActionMode(ActionMode mode) {
-        }
-
-        public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
-            return false;
-        }
-    };
-
     public void onClick(View v) {
         Object tag = v.getTag();
         if (tag instanceof ShortcutInfo) {
@@ -432,7 +433,7 @@
     /**
      * Creates a new UserFolder, inflated from R.layout.user_folder.
      *
-     * @param context The application's context.
+     * @param launcher The main activity.
      *
      * @return A new UserFolder.
      */
@@ -649,9 +650,8 @@
         oa.addListener(new AnimatorListenerAdapter() {
             @Override
             public void onAnimationEnd(Animator animation) {
-                onCloseComplete();
                 setLayerType(LAYER_TYPE_NONE, null);
-                mState = STATE_SMALL;
+                close();
             }
             @Override
             public void onAnimationStart(Animator animation) {
@@ -665,6 +665,32 @@
         oa.start();
     }
 
+    public void close() {
+        // TODO: Clear all active animations.
+        DragLayer parent = (DragLayer) getParent();
+        if (parent != null) {
+            parent.removeView(this);
+        }
+        mDragController.removeDropTarget(this);
+        clearFocus();
+        mFolderIcon.requestFocus();
+
+        if (mRearrangeOnClose) {
+            rearrangeChildren();
+            mRearrangeOnClose = false;
+        }
+        if (getItemCount() <= 1) {
+            if (!mDragInProgress && !mSuppressFolderDeletion) {
+                replaceFolderWithFinalItem();
+            } else if (mDragInProgress) {
+                mDeleteFolderOnDropCompleted = true;
+            }
+        }
+        mSuppressFolderDeletion = false;
+        clearDragInfo();
+        mState = STATE_SMALL;
+    }
+
     public boolean acceptDrop(DragObject d) {
         final ItemInfo item = d.dragInfo;
         final int itemType = item.itemType;
@@ -947,16 +973,6 @@
         LauncherModel.moveItemsInDatabase(mLauncher, items, mInfo.id, 0);
     }
 
-    public void addItemLocationsInDatabase() {
-        ArrayList<View> list = getItemsInReadingOrder();
-        for (int i = 0; i < list.size(); i++) {
-            View v = list.get(i);
-            ItemInfo info = (ItemInfo) v.getTag();
-            LauncherModel.addItemToDatabase(mLauncher, info, mInfo.id, 0,
-                    info.cellX, info.cellY);
-        }
-    }
-
     public void notifyDrop() {
         if (mDragInProgress) {
             mItemAddedBackToSelfViaIcon = true;
@@ -1093,39 +1109,10 @@
         mItemsInvalidated = true;
     }
 
-    // TODO remove this once GSA code fix is submitted
-    public ViewGroup getContent() {
-        return (ViewGroup) mContent;
-    }
-
     public int getItemCount() {
         return mContent.getItemCount();
     }
 
-    @Thunk void onCloseComplete() {
-        DragLayer parent = (DragLayer) getParent();
-        if (parent != null) {
-            parent.removeView(this);
-        }
-        mDragController.removeDropTarget((DropTarget) this);
-        clearFocus();
-        mFolderIcon.requestFocus();
-
-        if (mRearrangeOnClose) {
-            rearrangeChildren();
-            mRearrangeOnClose = false;
-        }
-        if (getItemCount() <= 1) {
-            if (!mDragInProgress && !mSuppressFolderDeletion) {
-                replaceFolderWithFinalItem();
-            } else if (mDragInProgress) {
-                mDeleteFolderOnDropCompleted = true;
-            }
-        }
-        mSuppressFolderDeletion = false;
-        clearDragInfo();
-    }
-
     @Thunk void replaceFolderWithFinalItem() {
         // Add the last remaining child to the workspace in place of the folder
         Runnable onCompleteRunnable = new Runnable() {
@@ -1344,10 +1331,6 @@
         return mItemsInReadingOrder;
     }
 
-    public void getLocationInDragLayer(int[] loc) {
-        mLauncher.getDragLayer().getLocationInDragLayer(this, loc);
-    }
-
     public void onFocusChange(View v, boolean hasFocus) {
         if (v == mFolderName && hasFocus) {
             startEditingFolderName();
@@ -1362,7 +1345,7 @@
     }
 
     @Override
-    public void fillInLaunchSourceData(Bundle sourceData) {
+    public void fillInLaunchSourceData(View v, Bundle sourceData) {
         // Fill in from the folder icon's launch source provider first
         Stats.LaunchSourceUtils.populateSourceDataFromAncestorProvider(mFolderIcon, sourceData);
         sourceData.putString(Stats.SOURCE_EXTRA_SUB_CONTAINER, Stats.SUB_CONTAINER_FOLDER);
diff --git a/src/com/android/launcher3/FolderIcon.java b/src/com/android/launcher3/FolderIcon.java
index 07bd0aa..7d1cb75 100644
--- a/src/com/android/launcher3/FolderIcon.java
+++ b/src/com/android/launcher3/FolderIcon.java
@@ -360,9 +360,6 @@
         mDragInfo = dragInfo;
     }
 
-    public void onDragOver(Object dragInfo) {
-    }
-
     OnAlarmListener mOnOpenListener = new OnAlarmListener() {
         public void onAlarm(Alarm alarm) {
             ShortcutInfo item;
diff --git a/src/com/android/launcher3/FolderPagedView.java b/src/com/android/launcher3/FolderPagedView.java
index 7aff832..594fa3c 100644
--- a/src/com/android/launcher3/FolderPagedView.java
+++ b/src/com/android/launcher3/FolderPagedView.java
@@ -227,12 +227,6 @@
         return (CellLayout) getChildAt(index);
     }
 
-    public void removeCellLayoutView(View view) {
-        for (int i = getChildCount() - 1; i >= 0; i --) {
-            getPageAt(i).removeView(view);
-        }
-    }
-
     public CellLayout getCurrentCellLayout() {
         return getPageAt(getNextPage());
     }
diff --git a/src/com/android/launcher3/Hotseat.java b/src/com/android/launcher3/Hotseat.java
index 98912f5..902b6ec 100644
--- a/src/com/android/launcher3/Hotseat.java
+++ b/src/com/android/launcher3/Hotseat.java
@@ -23,6 +23,7 @@
 import android.util.AttributeSet;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
+import android.view.View;
 import android.widget.FrameLayout;
 import android.widget.TextView;
 
@@ -153,7 +154,7 @@
     }
 
     @Override
-    public void fillInLaunchSourceData(Bundle sourceData) {
+    public void fillInLaunchSourceData(View v, Bundle sourceData) {
         sourceData.putString(Stats.SOURCE_EXTRA_CONTAINER, Stats.CONTAINER_HOTSEAT);
     }
 }
diff --git a/src/com/android/launcher3/IconCache.java b/src/com/android/launcher3/IconCache.java
index bf8ee9d..1cf31fd 100644
--- a/src/com/android/launcher3/IconCache.java
+++ b/src/com/android/launcher3/IconCache.java
@@ -180,15 +180,7 @@
 
     private Bitmap makeDefaultIcon(UserHandleCompat user) {
         Drawable unbadged = getFullResDefaultActivityIcon();
-        Drawable d = mUserManager.getBadgedDrawableForUser(unbadged, user);
-        Bitmap b = Bitmap.createBitmap(Math.max(d.getIntrinsicWidth(), 1),
-                Math.max(d.getIntrinsicHeight(), 1),
-                Bitmap.Config.ARGB_8888);
-        Canvas c = new Canvas(b);
-        d.setBounds(0, 0, b.getWidth(), b.getHeight());
-        d.draw(c);
-        c.setBitmap(null);
-        return b;
+        return Utilities.createBadgedIconBitmap(unbadged, user, mContext);
     }
 
     /**
@@ -381,7 +373,8 @@
         }
         if (entry == null) {
             entry = new CacheEntry();
-            entry.icon = Utilities.createIconBitmap(app.getBadgedIcon(mIconDpi), mContext);
+            entry.icon = Utilities.createBadgedIconBitmap(
+                    app.getIcon(mIconDpi), app.getUser(), mContext);
         }
         entry.title = app.getLabel();
         entry.contentDescription = mUserManager.getBadgedLabelForUser(entry.title, app.getUser());
@@ -544,7 +537,8 @@
             // Check the DB first.
             if (!getEntryFromDB(cacheKey, entry, useLowResIcon)) {
                 if (info != null) {
-                    entry.icon = Utilities.createIconBitmap(info.getBadgedIcon(mIconDpi), mContext);
+                    entry.icon = Utilities.createBadgedIconBitmap(
+                            info.getIcon(mIconDpi), info.getUser(), mContext);
                 } else {
                     if (usePackageIcon) {
                         CacheEntry packageEntry = getEntryForPackageLocked(
@@ -628,9 +622,8 @@
 
                     // Load the full res icon for the application, but if useLowResIcon is set, then
                     // only keep the low resolution icon instead of the larger full-sized icon
-                    Drawable drawable = mUserManager.getBadgedDrawableForUser(
-                            appInfo.loadIcon(mPackageManager), user);
-                    Bitmap icon = Utilities.createIconBitmap(drawable, mContext);
+                    Bitmap icon = Utilities.createBadgedIconBitmap(
+                            appInfo.loadIcon(mPackageManager), user, mContext);
                     Bitmap lowResIcon =  generateLowResIcon(icon, mPackageBgColor);
                     entry.title = appInfo.loadLabel(mPackageManager);
                     entry.contentDescription = mUserManager.getBadgedLabelForUser(entry.title, user);
diff --git a/src/com/android/launcher3/InstallShortcutReceiver.java b/src/com/android/launcher3/InstallShortcutReceiver.java
index 3fc8fc0..9a75193 100644
--- a/src/com/android/launcher3/InstallShortcutReceiver.java
+++ b/src/com/android/launcher3/InstallShortcutReceiver.java
@@ -92,8 +92,7 @@
         if (packageNames.isEmpty()) {
             return;
         }
-        String spKey = LauncherAppState.getSharedPreferencesKey();
-        SharedPreferences sp = context.getSharedPreferences(spKey, Context.MODE_PRIVATE);
+        SharedPreferences sp = Utilities.getPrefs(context);
         synchronized(sLock) {
             Set<String> strings = sp.getStringSet(APPS_PENDING_INSTALL, null);
             if (DBG) {
@@ -176,9 +175,7 @@
         LauncherAppState app = LauncherAppState.getInstance();
         boolean launcherNotLoaded = app.getModel().getCallback() == null;
 
-        String spKey = LauncherAppState.getSharedPreferencesKey();
-        SharedPreferences sp = context.getSharedPreferences(spKey, Context.MODE_PRIVATE);
-        addToInstallQueue(sp, info);
+        addToInstallQueue(Utilities.getPrefs(context), info);
         if (!mUseInstallQueue && !launcherNotLoaded) {
             flushInstallQueue(context);
         }
@@ -192,8 +189,7 @@
         flushInstallQueue(context);
     }
     static void flushInstallQueue(Context context) {
-        String spKey = LauncherAppState.getSharedPreferencesKey();
-        SharedPreferences sp = context.getSharedPreferences(spKey, Context.MODE_PRIVATE);
+        SharedPreferences sp = Utilities.getPrefs(context);
         ArrayList<PendingInstallShortcutInfo> installQueue = getAndClearInstallQueue(sp, context);
         if (!installQueue.isEmpty()) {
             Iterator<PendingInstallShortcutInfo> iter = installQueue.iterator();
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 750d211..cca0e36 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -16,6 +16,7 @@
 
 package com.android.launcher3;
 
+import android.Manifest;
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.AnimatorSet;
@@ -46,12 +47,12 @@
 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.Configuration;
 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.ColorDrawable;
@@ -152,6 +153,8 @@
     private static final int REQUEST_BIND_APPWIDGET = 11;
     private static final int REQUEST_RECONFIGURE_APPWIDGET = 12;
 
+    private static final int REQUEST_PERMISSION_CALL_PHONE = 13;
+
     private static final int WORKSPACE_BACKGROUND_GRADIENT = 0;
     private static final int WORKSPACE_BACKGROUND_TRANSPARENT = 1;
     private static final int WORKSPACE_BACKGROUND_BLACK = 2;
@@ -412,8 +415,7 @@
                 app.getInvariantDeviceProfile().landscapeProfile
                 : app.getInvariantDeviceProfile().portraitProfile;
 
-        mSharedPrefs = getSharedPreferences(LauncherAppState.getSharedPreferencesKey(),
-                Context.MODE_PRIVATE);
+        mSharedPrefs = Utilities.getPrefs(this);
         mIsSafeModeEnabled = getPackageManager().isSafeMode();
         mModel = app.setLauncher(this);
         mIconCache = app.getIconCache();
@@ -440,6 +442,8 @@
 
         setContentView(R.layout.launcher);
 
+        app.getInvariantDeviceProfile().landscapeProfile.setSearchBarHeight(getSearchBarHeight());
+        app.getInvariantDeviceProfile().portraitProfile.setSearchBarHeight(getSearchBarHeight());
         setupViews();
         mDeviceProfile.layout(this);
 
@@ -822,6 +826,24 @@
     /** @Override for MNC */
     public void onRequestPermissionsResult(int requestCode, String[] permissions,
             int[] grantResults) {
+        if (requestCode == REQUEST_PERMISSION_CALL_PHONE && sPendingAddItem != null
+                && sPendingAddItem.requestCode == REQUEST_PERMISSION_CALL_PHONE) {
+            View v = null;
+            CellLayout layout = getCellLayout(sPendingAddItem.container, sPendingAddItem.screenId);
+            if (layout != null) {
+                v = layout.getChildAt(sPendingAddItem.cellX, sPendingAddItem.cellY);
+            }
+            Intent intent = sPendingAddItem.intent;
+            sPendingAddItem = null;
+            if (grantResults.length > 0
+                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+                startActivity(v, intent, null);
+            } else {
+                // TODO: Show a snack bar with link to settings
+                Toast.makeText(this, getString(R.string.msg_no_phone_permission,
+                        getString(R.string.app_name)), Toast.LENGTH_SHORT).show();
+            }
+        }
         if (mLauncherCallbacks != null) {
             mLauncherCallbacks.onRequestPermissionsResult(requestCode, permissions,
                     grantResults);
@@ -1243,7 +1265,7 @@
                 if (mState == State.WORKSPACE && !mWorkspace.isInOverviewMode() &&
                         !mWorkspace.isSwitchingState()) {
                     mOverviewPanel.requestFocus();
-                    showOverviewMode(true);
+                    showOverviewMode(true, true /* requestButtonFocus */);
                 }
             }
             return true;
@@ -1338,55 +1360,8 @@
             mHotseat.setOnLongClickListener(this);
         }
 
-        mOverviewPanel = (ViewGroup) findViewById(R.id.overview_panel);
-        // Long-clicking buttons in the overview panel does the same thing as clicking them.
-        OnLongClickListener performClickOnLongClick = new OnLongClickListener() {
-            @Override
-            public boolean onLongClick(View v) {
-                return v.performClick();
-            }
-        };
-        mWidgetsButton = findViewById(R.id.widget_button);
-        mWidgetsButton.setOnClickListener(new OnClickListener() {
-            @Override
-            public void onClick(View view) {
-                if (!mWorkspace.isSwitchingState()) {
-                    onClickAddWidgetButton(view);
-                }
-            }
-        });
-        mWidgetsButton.setOnLongClickListener(performClickOnLongClick);
-        mWidgetsButton.setOnTouchListener(getHapticFeedbackTouchListener());
-
-        View wallpaperButton = findViewById(R.id.wallpaper_button);
-        wallpaperButton.setOnClickListener(new OnClickListener() {
-            @Override
-            public void onClick(View view) {
-                if (!mWorkspace.isSwitchingState()) {
-                    onClickWallpaperPicker(view);
-                }
-            }
-        });
-        wallpaperButton.setOnLongClickListener(performClickOnLongClick);
-        wallpaperButton.setOnTouchListener(getHapticFeedbackTouchListener());
-
-        View settingsButton = findViewById(R.id.settings_button);
-        if (hasSettings()) {
-            settingsButton.setOnClickListener(new OnClickListener() {
-                @Override
-                public void onClick(View view) {
-                    if (!mWorkspace.isSwitchingState()) {
-                        onClickSettingsButton(view);
-                    }
-                }
-            });
-            settingsButton.setOnLongClickListener(performClickOnLongClick);
-            settingsButton.setOnTouchListener(getHapticFeedbackTouchListener());
-        } else {
-            settingsButton.setVisibility(View.GONE);
-        }
-
-        mOverviewPanel.setAlpha(0f);
+        // Setup the overview panel
+        setupOverviewPanel();
 
         // Setup the workspace
         mWorkspace.setHapticFeedbackEnabled(false);
@@ -1427,6 +1402,64 @@
         }
     }
 
+    private void setupOverviewPanel() {
+        mOverviewPanel = (ViewGroup) findViewById(R.id.overview_panel);
+
+        // Long-clicking buttons in the overview panel does the same thing as clicking them.
+        OnLongClickListener performClickOnLongClick = new OnLongClickListener() {
+            @Override
+            public boolean onLongClick(View v) {
+                return v.performClick();
+            }
+        };
+
+        // Bind wallpaper button actions
+        View wallpaperButton = findViewById(R.id.wallpaper_button);
+        wallpaperButton.setOnClickListener(new OnClickListener() {
+            @Override
+            public void onClick(View view) {
+                if (!mWorkspace.isSwitchingState()) {
+                    onClickWallpaperPicker(view);
+                }
+            }
+        });
+        wallpaperButton.setOnLongClickListener(performClickOnLongClick);
+        wallpaperButton.setOnTouchListener(getHapticFeedbackTouchListener());
+
+        // Bind widget button actions
+        mWidgetsButton = findViewById(R.id.widget_button);
+        mWidgetsButton.setOnClickListener(new OnClickListener() {
+            @Override
+            public void onClick(View view) {
+                if (!mWorkspace.isSwitchingState()) {
+                    onClickAddWidgetButton(view);
+                }
+            }
+        });
+        mWidgetsButton.setOnLongClickListener(performClickOnLongClick);
+        mWidgetsButton.setOnTouchListener(getHapticFeedbackTouchListener());
+
+        // Bind settings actions
+        View settingsButton = findViewById(R.id.settings_button);
+        boolean hasSettings = hasSettings();
+        if (hasSettings) {
+            settingsButton.setOnClickListener(new OnClickListener() {
+                @Override
+                public void onClick(View view) {
+                    if (!mWorkspace.isSwitchingState()) {
+                        onClickSettingsButton(view);
+                    }
+                }
+            });
+            settingsButton.setOnLongClickListener(performClickOnLongClick);
+            settingsButton.setOnTouchListener(getHapticFeedbackTouchListener());
+        } else {
+            settingsButton.setVisibility(View.GONE);
+        }
+
+        mOverviewPanel.setAlpha(0f);
+    }
+
     /**
      * Sets the all apps button. This method is called from {@link Hotseat}.
      */
@@ -1681,14 +1714,14 @@
                         mWorkspace.postDelayed(mBuildLayersRunnable, 500);
                         final ViewTreeObserver.OnDrawListener listener = this;
                         mWorkspace.post(new Runnable() {
-                                public void run() {
-                                    if (mWorkspace != null &&
-                                            mWorkspace.getViewTreeObserver() != null) {
-                                        mWorkspace.getViewTreeObserver().
-                                                removeOnDrawListener(listener);
-                                    }
+                            public void run() {
+                                if (mWorkspace != null &&
+                                        mWorkspace.getViewTreeObserver() != null) {
+                                    mWorkspace.getViewTreeObserver().
+                                            removeOnDrawListener(listener);
                                 }
-                            });
+                            }
+                        });
                         return;
                     }
                 });
@@ -1848,7 +1881,7 @@
             // In all these cases, only animate if we're already on home
             mWorkspace.exitWidgetResizeMode();
 
-            closeFolder();
+            closeFolder(alreadyOnHome);
             exitSpringLoadedDragMode();
 
             // If we are already on home, then just animate back to the workspace,
@@ -1861,7 +1894,7 @@
 
             final View v = getWindow().peekDecorView();
             if (v != null && v.getWindowToken() != null) {
-                InputMethodManager imm = (InputMethodManager)getSystemService(
+                InputMethodManager imm = (InputMethodManager) getSystemService(
                         INPUT_METHOD_SERVICE);
                 imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
             }
@@ -1900,7 +1933,9 @@
                 mWorkspace.post(new Runnable() {
                     @Override
                     public void run() {
-                        mWorkspace.moveToDefaultScreen(true);
+                        if (mWorkspace != null) {
+                            mWorkspace.moveToDefaultScreen(true);
+                        }
                     }
                 });
             }
@@ -1930,7 +1965,7 @@
         outState.putInt(RUNTIME_STATE, mState.ordinal());
         // We close any open folder since it will not be re-opened, and we need to make sure
         // this state is reflected.
-        closeFolder();
+        closeFolder(false);
 
         if (mPendingAddInfo.container != ItemInfo.NO_ID && mPendingAddInfo.screenId > -1 &&
                 mWaitingForResult) {
@@ -2179,8 +2214,11 @@
         mPendingAddInfo.minSpanX = mPendingAddInfo.minSpanY = 1;
     }
 
-    void addAppWidgetImpl(final int appWidgetId, final ItemInfo info, final
+    void addAppWidgetFromDropImpl(final int appWidgetId, final ItemInfo info, final
             AppWidgetHostView boundWidget, final LauncherAppWidgetProviderInfo appWidgetInfo) {
+        if (LOGD) {
+            Log.d(TAG, "Adding widget from drop");
+        }
         addAppWidgetImpl(appWidgetId, info, boundWidget, appWidgetInfo, 0);
     }
 
@@ -2286,8 +2324,14 @@
         AppWidgetHostView hostView = info.boundWidget;
         int appWidgetId;
         if (hostView != null) {
+            // In the case where we've prebound the widget, we remove it from the DragLayer
+            if (LOGD) {
+                Log.d(TAG, "Removing widget view from drag layer and setting boundWidget to null");
+            }
+            getDragLayer().removeView(hostView);
+
             appWidgetId = hostView.getAppWidgetId();
-            addAppWidgetImpl(appWidgetId, info, hostView, info.info);
+            addAppWidgetFromDropImpl(appWidgetId, info, hostView, info.info);
 
             // Clear the boundWidget so that it doesn't get destroyed.
             info.boundWidget = null;
@@ -2300,7 +2344,7 @@
             boolean success = mAppWidgetManager.bindAppWidgetIdIfAllowed(
                     appWidgetId, info.info, options);
             if (success) {
-                addAppWidgetImpl(appWidgetId, info, null, info.info);
+                addAppWidgetFromDropImpl(appWidgetId, info, null, info.info);
             } else {
                 mPendingAddWidgetInfo = info.info;
                 Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND);
@@ -2711,7 +2755,7 @@
             if (openFolder != null) {
                 folderScreen = mWorkspace.getPageForView(openFolder);
                 // .. and close it
-                closeFolder(openFolder);
+                closeFolder(openFolder, true);
                 if (folderScreen != mWorkspace.getCurrentPage()) {
                     // Close any folder open on the current screen
                     closeFolder();
@@ -2933,6 +2977,22 @@
             }
             return true;
         } catch (SecurityException e) {
+            if (Utilities.ATLEAST_MARSHMALLOW && tag instanceof ItemInfo) {
+                // Due to legacy reasons, direct call shortcuts require Launchers to have the
+                // corresponding permission. Show the appropriate permission prompt if that
+                // is the case.
+                if (intent.getComponent() == null
+                        && Intent.ACTION_CALL.equals(intent.getAction())
+                        && checkSelfPermission(Manifest.permission.CALL_PHONE) !=
+                            PackageManager.PERMISSION_GRANTED) {
+                    // TODO: Rename sPendingAddItem to a generic name.
+                    sPendingAddItem = preparePendingAddArgs(REQUEST_PERMISSION_CALL_PHONE, intent,
+                            0, (ItemInfo) tag);
+                    requestPermissions(new String[]{Manifest.permission.CALL_PHONE},
+                            REQUEST_PERMISSION_CALL_PHONE);
+                    return false;
+                }
+            }
             Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
             Log.e(TAG, "Launcher does not have the permission to launch " + intent +
                     ". Make sure to create a MAIN intent-filter for the corresponding activity " +
@@ -3031,7 +3091,7 @@
         oa.start();
     }
 
-    private void shrinkAndFadeInFolderIcon(final FolderIcon fi) {
+    private void shrinkAndFadeInFolderIcon(final FolderIcon fi, boolean animate) {
         if (fi == null) return;
         final CellLayout cl = (CellLayout) fi.getParent().getParent();
 
@@ -3052,6 +3112,9 @@
             }
         });
         oa.start();
+        if (!animate) {
+            oa.end();
+        }
     }
 
     /**
@@ -3095,30 +3158,38 @@
     }
 
     public void closeFolder() {
+        closeFolder(true);
+    }
+
+    public void closeFolder(boolean animate) {
         Folder folder = mWorkspace != null ? mWorkspace.getOpenFolder() : null;
         if (folder != null) {
             if (folder.isEditingName()) {
                 folder.dismissEditingName();
             }
-            closeFolder(folder);
+            closeFolder(folder, animate);
         }
     }
 
-    public void closeFolder(Folder folder) {
+    public void closeFolder(Folder folder, boolean animate) {
         folder.getInfo().opened = false;
 
         ViewGroup parent = (ViewGroup) folder.getParent().getParent();
         if (parent != null) {
             FolderIcon fi = (FolderIcon) mWorkspace.getViewForTag(folder.mInfo);
-            shrinkAndFadeInFolderIcon(fi);
+            shrinkAndFadeInFolderIcon(fi, animate);
             if (fi != null) {
                 ((CellLayout.LayoutParams) fi.getLayoutParams()).canReorder = true;
             }
         }
-        folder.animateClosed();
+        if (animate) {
+            folder.animateClosed();
+        } else {
+            folder.close();
+        }
 
-        // Notify the accessibility manager that this folder "window" has disappeard and no
-        // longer occludeds the workspace items
+        // Notify the accessibility manager that this folder "window" has disappeared and no
+        // longer occludes the workspace items
         getDragLayer().sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
     }
 
@@ -3290,10 +3361,33 @@
         return changed;
     }
 
+    /**
+     * Shows the overview button.
+     */
     void showOverviewMode(boolean animated) {
+        showOverviewMode(animated, false);
+    }
+
+    /**
+     * Shows the overview button, and if {@param requestButtonFocus} is set, will force the focus
+     * onto one of the overview panel buttons.
+     */
+    void showOverviewMode(boolean animated, boolean requestButtonFocus) {
+        Runnable postAnimRunnable = null;
+        if (requestButtonFocus) {
+            postAnimRunnable = new Runnable() {
+                @Override
+                public void run() {
+                    // Hitting the menu button when in touch mode does not trigger touch mode to
+                    // be disabled, so if requested, force focus on one of the overview panel
+                    // buttons.
+                    mOverviewPanel.requestFocusFromTouch();
+                }
+            };
+        }
         mWorkspace.setVisibility(View.VISIBLE);
         mStateTransitionAnimation.startAnimationToWorkspace(mState, mWorkspace.getState(),
-                Workspace.State.OVERVIEW, animated, null /* onCompleteRunnable */);
+                Workspace.State.OVERVIEW, animated, postAnimRunnable);
         mState = State.WORKSPACE;
     }
 
@@ -3496,29 +3590,35 @@
             DeviceProfile portraitProfile = app.getInvariantDeviceProfile().portraitProfile;
             DeviceProfile landscapeProfile = app.getInvariantDeviceProfile().landscapeProfile;
             float density = getResources().getDisplayMetrics().density;
-            Rect searchBounds = portraitProfile.getSearchBarBounds(Utilities.isRtl(getResources()));
-            int maxHeight = (int) (searchBounds.height() / density);
+            Point searchDimens = portraitProfile.getSearchBarDimensForWidgetOpts(getResources());
+            int maxHeight = (int) (searchDimens.y / density);
             int minHeight = maxHeight;
-            int maxWidth = (int) (searchBounds.width() / density);
+            int maxWidth = (int) (searchDimens.x / density);
             int minWidth = maxWidth;
             if (!landscapeProfile.isVerticalBarLayout()) {
-                searchBounds = landscapeProfile.getSearchBarBounds(Utilities.isRtl(getResources()));
-                maxHeight = (int) Math.max(maxHeight, searchBounds.height() / density);
-                minHeight = (int) Math.min(minHeight, searchBounds.height() / density);
-                maxWidth = (int) Math.max(maxWidth, searchBounds.width() / density);
-                minWidth = (int) Math.min(minWidth, searchBounds.width() / density);
+                searchDimens = landscapeProfile.getSearchBarDimensForWidgetOpts(getResources());
+                maxHeight = (int) Math.max(maxHeight, searchDimens.y / density);
+                minHeight = (int) Math.min(minHeight, searchDimens.y / density);
+                maxWidth = (int) Math.max(maxWidth, searchDimens.x / density);
+                minWidth = (int) Math.min(minWidth, searchDimens.x / density);
             }
             opts.putInt(AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT, maxHeight);
             opts.putInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT, minHeight);
             opts.putInt(AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH, maxWidth);
             opts.putInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH, minWidth);
+            if (LOGD) {
+                Log.d(TAG, "QSB widget options: maxHeight=" + maxHeight + " minHeight=" + minHeight
+                        + " maxWidth=" + maxWidth + " minWidth=" + minWidth);
+            }
 
-            SharedPreferences sp = getSharedPreferences(
-                    LauncherAppState.getSharedPreferencesKey(), MODE_PRIVATE);
-            int widgetId = sp.getInt(QSB_WIDGET_ID, -1);
+            if (mLauncherCallbacks != null) {
+                opts.putAll(mLauncherCallbacks.getAdditionalSearchWidgetOptions());
+            }
+
+            int widgetId = mSharedPrefs.getInt(QSB_WIDGET_ID, -1);
             AppWidgetProviderInfo widgetInfo = mAppWidgetManager.getAppWidgetInfo(widgetId);
             if (!searchProvider.provider.flattenToString().equals(
-                    sp.getString(QSB_WIDGET_PROVIDER, null))
+                    mSharedPrefs.getString(QSB_WIDGET_PROVIDER, null))
                     || (widgetInfo == null)
                     || !widgetInfo.provider.equals(searchProvider.provider)) {
                 // A valid widget is not already bound.
@@ -3536,7 +3636,7 @@
                     widgetId = -1;
                 }
 
-                sp.edit()
+                mSharedPrefs.edit()
                     .putInt(QSB_WIDGET_ID, widgetId)
                     .putString(QSB_WIDGET_PROVIDER, searchProvider.provider.flattenToString())
                     .commit();
diff --git a/src/com/android/launcher3/LauncherAppState.java b/src/com/android/launcher3/LauncherAppState.java
index 3b207a9..6ce7c5f 100644
--- a/src/com/android/launcher3/LauncherAppState.java
+++ b/src/com/android/launcher3/LauncherAppState.java
@@ -134,7 +134,7 @@
     }
 
     LauncherModel setLauncher(Launcher launcher) {
-        getLauncherProvider().setLauncherProviderChangeListener(launcher);
+        sLauncherProvider.get().setLauncherProviderChangeListener(launcher);
         mModel.initialize(launcher);
         mAccessibilityDelegate = ((launcher != null) && Utilities.ATLEAST_LOLLIPOP) ?
             new LauncherAccessibilityDelegate(launcher) : null;
@@ -157,14 +157,6 @@
         sLauncherProvider = new WeakReference<LauncherProvider>(provider);
     }
 
-    public static LauncherProvider getLauncherProvider() {
-        return sLauncherProvider.get();
-    }
-
-    public static String getSharedPreferencesKey() {
-        return LauncherFiles.SHARED_PREFERENCES_KEY;
-    }
-
     public WidgetPreviewLoader getWidgetCache() {
         return mWidgetCache;
     }
diff --git a/src/com/android/launcher3/LauncherAppWidgetHost.java b/src/com/android/launcher3/LauncherAppWidgetHost.java
index 28c5eac..b07ccc3 100644
--- a/src/com/android/launcher3/LauncherAppWidgetHost.java
+++ b/src/com/android/launcher3/LauncherAppWidgetHost.java
@@ -20,6 +20,7 @@
 import android.appwidget.AppWidgetHostView;
 import android.appwidget.AppWidgetProviderInfo;
 import android.content.Context;
+import android.os.DeadObjectException;
 import android.os.TransactionTooLargeException;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -69,7 +70,8 @@
         try {
             super.startListening();
         } catch (Exception e) {
-            if (e.getCause() instanceof TransactionTooLargeException) {
+            if (e.getCause() instanceof TransactionTooLargeException ||
+                    e.getCause() instanceof DeadObjectException) {
                 // We're willing to let this slide. The exception is being caused by the list of
                 // RemoteViews which is being passed back. The startListening relationship will
                 // have been established by this point, and we will end up populating the
diff --git a/src/com/android/launcher3/LauncherBackupAgentHelper.java b/src/com/android/launcher3/LauncherBackupAgentHelper.java
index 8eb4e63..2a5f197 100644
--- a/src/com/android/launcher3/LauncherBackupAgentHelper.java
+++ b/src/com/android/launcher3/LauncherBackupAgentHelper.java
@@ -73,7 +73,8 @@
         }
 
         // Clear dB before restore
-        LauncherAppState.getLauncherProvider().createEmptyDB();
+        LauncherSettings.Settings.call(getContentResolver(),
+                LauncherSettings.Settings.METHOD_CREATE_EMPTY_DB);
 
         boolean hasData;
         try {
@@ -90,12 +91,14 @@
         }
 
         if (hasData && mHelper.restoreSuccessful) {
-            LauncherAppState.getLauncherProvider().clearFlagEmptyDbCreated();
+            LauncherSettings.Settings.call(getContentResolver(),
+                    LauncherSettings.Settings.METHOD_CLEAR_EMPTY_DB_FLAG);
             LauncherClings.synchonouslyMarkFirstRunClingDismissed(this);
 
             // Rank was added in v4.
             if (mHelper.restoredBackupVersion <= 3) {
-                LauncherAppState.getLauncherProvider().updateFolderItemsRank();
+                LauncherSettings.Settings.call(getContentResolver(),
+                        LauncherSettings.Settings.METHOD_UPDATE_FOLDER_ITEMS_RANK);
             }
 
             if (MigrateFromRestoreTask.ENABLED && mHelper.shouldAttemptWorkspaceMigration()) {
@@ -105,10 +108,12 @@
                         mHelper.widgetSizes);
             }
 
-            LauncherAppState.getLauncherProvider().convertShortcutsToLauncherActivities();
+            LauncherSettings.Settings.call(getContentResolver(),
+                    LauncherSettings.Settings.METHOD_CONVERT_SHORTCUTS_TO_ACTIVITIES);
         } else {
             if (VERBOSE) Log.v(TAG, "Nothing was restored, clearing DB");
-            LauncherAppState.getLauncherProvider().createEmptyDB();
+            LauncherSettings.Settings.call(getContentResolver(),
+                    LauncherSettings.Settings.METHOD_CREATE_EMPTY_DB);
         }
     }
 }
diff --git a/src/com/android/launcher3/LauncherCallbacks.java b/src/com/android/launcher3/LauncherCallbacks.java
index 927db22..f27ed1d 100644
--- a/src/com/android/launcher3/LauncherCallbacks.java
+++ b/src/com/android/launcher3/LauncherCallbacks.java
@@ -83,6 +83,7 @@
     public boolean hasCustomContentToLeft();
     public void populateCustomContentContainer();
     public View getQsbBar();
+    public Bundle getAdditionalSearchWidgetOptions();
 
     /*
      * Extensions points for adding / replacing some other aspects of the Launcher experience.
diff --git a/src/com/android/launcher3/LauncherClings.java b/src/com/android/launcher3/LauncherClings.java
index 43d05a6..cffcbf2 100644
--- a/src/com/android/launcher3/LauncherClings.java
+++ b/src/com/android/launcher3/LauncherClings.java
@@ -75,9 +75,7 @@
                     LauncherModel.LOADER_FLAG_CLEAR_WORKSPACE
                             | LauncherModel.LOADER_FLAG_MIGRATE_SHORTCUTS);
             // Set the flag to skip the folder cling
-            String spKey = LauncherAppState.getSharedPreferencesKey();
-            SharedPreferences sp = mLauncher.getSharedPreferences(spKey, Context.MODE_PRIVATE);
-            SharedPreferences.Editor editor = sp.edit();
+            SharedPreferences.Editor editor = Utilities.getPrefs(mLauncher).edit();
             editor.putBoolean(Launcher.USER_HAS_MIGRATED, true);
             editor.apply();
             // Disable the migration cling
@@ -279,9 +277,7 @@
     }
 
     public static void synchonouslyMarkFirstRunClingDismissed(Context ctx) {
-        SharedPreferences prefs = ctx.getSharedPreferences(
-                LauncherAppState.getSharedPreferencesKey(), Context.MODE_PRIVATE);
-        SharedPreferences.Editor editor = prefs.edit();
+        SharedPreferences.Editor editor = Utilities.getPrefs(ctx).edit();
         editor.putBoolean(WORKSPACE_CLING_DISMISSED_KEY, true);
         editor.commit();
     }
diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java
index 5711db0..19d851d 100644
--- a/src/com/android/launcher3/LauncherModel.java
+++ b/src/com/android/launcher3/LauncherModel.java
@@ -481,7 +481,9 @@
 
         if (!found) {
             // Still no position found. Add a new screen to the end.
-            screenId = LauncherAppState.getLauncherProvider().generateNewScreenId();
+            screenId = LauncherSettings.Settings.call(context.getContentResolver(),
+                    LauncherSettings.Settings.METHOD_NEW_SCREEN_ID)
+                    .getLong(LauncherSettings.Settings.EXTRA_VALUE);
 
             // Save the screen id for binding in the workspace
             workspaceScreens.add(screenId);
@@ -526,8 +528,7 @@
 
                         // Find appropriate space for the item.
                         Pair<Long, int[]> coords = findSpaceForItem(context,
-                                workspaceScreens, addedWorkspaceScreensFinal,
-                                1, 1);
+                                workspaceScreens, addedWorkspaceScreensFinal, 1, 1);
                         long screenId = coords.first;
                         int[] cordinates = coords.second;
 
@@ -924,51 +925,6 @@
     }
 
     /**
-     * Find a folder in the db, creating the FolderInfo if necessary, and adding it to folderList.
-     */
-    FolderInfo getFolderById(Context context, LongArrayMap<FolderInfo> folderList, long id) {
-        final ContentResolver cr = context.getContentResolver();
-        Cursor c = cr.query(LauncherSettings.Favorites.CONTENT_URI, null,
-                "_id=? and (itemType=? or itemType=?)",
-                new String[] { String.valueOf(id),
-                        String.valueOf(LauncherSettings.Favorites.ITEM_TYPE_FOLDER)}, null);
-
-        try {
-            if (c.moveToFirst()) {
-                final int itemTypeIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ITEM_TYPE);
-                final int titleIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.TITLE);
-                final int containerIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CONTAINER);
-                final int screenIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SCREEN);
-                final int cellXIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLX);
-                final int cellYIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLY);
-                final int optionsIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.OPTIONS);
-
-                FolderInfo folderInfo = null;
-                switch (c.getInt(itemTypeIndex)) {
-                    case LauncherSettings.Favorites.ITEM_TYPE_FOLDER:
-                        folderInfo = findOrMakeFolder(folderList, id);
-                        break;
-                }
-
-                // Do not trim the folder label, as is was set by the user.
-                folderInfo.title = c.getString(titleIndex);
-                folderInfo.id = id;
-                folderInfo.container = c.getInt(containerIndex);
-                folderInfo.screenId = c.getInt(screenIndex);
-                folderInfo.cellX = c.getInt(cellXIndex);
-                folderInfo.cellY = c.getInt(cellYIndex);
-                folderInfo.options = c.getInt(optionsIndex);
-
-                return folderInfo;
-            }
-        } finally {
-            c.close();
-        }
-
-        return null;
-    }
-
-    /**
      * Add an item to the database in a specified container. Sets the container, screen, cellX and
      * cellY fields of the item. Also assigns an ID to the item.
      */
@@ -990,7 +946,9 @@
         final ContentResolver cr = context.getContentResolver();
         item.onAddToDatabase(context, values);
 
-        item.id = LauncherAppState.getLauncherProvider().generateNewItemId();
+        item.id = LauncherSettings.Settings.call(cr, LauncherSettings.Settings.METHOD_NEW_ITEM_ID)
+                .getLong(LauncherSettings.Settings.EXTRA_VALUE);
+
         values.put(LauncherSettings.Favorites._ID, item.id);
 
         final StackTraceElement[] stackTrace = new Throwable().getStackTrace();
@@ -1030,15 +988,6 @@
         runOnWorkerThread(r);
     }
 
-    /**
-     * Creates a new unique child id, for a given cell span across all layouts.
-     */
-    static int getCellLayoutChildId(
-            long container, long screen, int localCellX, int localCellY, int spanX, int spanY) {
-        return (((int) container & 0xFF) << 24)
-                | ((int) screen & 0xFF) << 16 | (localCellX & 0xFF) << 8 | (localCellY & 0xFF);
-    }
-
     private static ArrayList<ItemInfo> getItemsByPackageName(
             final String pn, final UserHandleCompat user) {
         ItemInfoFilter filter  = new ItemInfoFilter() {
@@ -1392,10 +1341,6 @@
         return screenIds;
     }
 
-    public boolean isAllAppsLoaded() {
-        return mAllAppsLoaded;
-    }
-
     /**
      * Runnable for the thread that loads the contents of the launcher:
      *   - workspace icons
@@ -1727,17 +1672,20 @@
 
             if ((mFlags & LOADER_FLAG_CLEAR_WORKSPACE) != 0) {
                 Log.d(TAG, "loadWorkspace: resetting launcher database");
-                LauncherAppState.getLauncherProvider().deleteDatabase();
+                LauncherSettings.Settings.call(contentResolver,
+                        LauncherSettings.Settings.METHOD_DELETE_DB);
             }
 
             if ((mFlags & LOADER_FLAG_MIGRATE_SHORTCUTS) != 0) {
                 // append the user's Launcher2 shortcuts
                 Log.d(TAG, "loadWorkspace: migrating from launcher2");
-                LauncherAppState.getLauncherProvider().migrateLauncher2Shortcuts();
+                LauncherSettings.Settings.call(contentResolver,
+                        LauncherSettings.Settings.METHOD_MIGRATE_LAUNCHER2_SHORTCUTS);
             } else {
                 // Make sure the default workspace is loaded
                 Log.d(TAG, "loadWorkspace: loading default favorites");
-                LauncherAppState.getLauncherProvider().loadDefaultFavoritesIfNecessary();
+                LauncherSettings.Settings.call(contentResolver,
+                        LauncherSettings.Settings.METHOD_LOAD_DEFAULT_FAVORITES);
             }
 
             synchronized (sBgLock) {
@@ -2232,8 +2180,11 @@
                     }
 
                     // Remove any empty folder
-                    for (long folderId : LauncherAppState.getLauncherProvider()
-                            .deleteEmptyFolders()) {
+                    ArrayList<Long> deletedFolderIds = (ArrayList<Long>) LauncherSettings.Settings
+                            .call(contentResolver,
+                                    LauncherSettings.Settings.METHOD_DELETE_EMPTY_FOLDERS)
+                            .getSerializable(LauncherSettings.Settings.EXTRA_VALUE);
+                    for (long folderId : deletedFolderIds) {
                         sBgWorkspaceItems.remove(sBgFolders.get(folderId));
                         sBgFolders.remove(folderId);
                         sBgItemsIdMap.remove(folderId);
diff --git a/src/com/android/launcher3/LauncherProvider.java b/src/com/android/launcher3/LauncherProvider.java
index 0c56713..17e2820 100644
--- a/src/com/android/launcher3/LauncherProvider.java
+++ b/src/com/android/launcher3/LauncherProvider.java
@@ -62,7 +62,6 @@
 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 = "LauncherProvider";
@@ -91,10 +90,6 @@
         return true;
     }
 
-    public boolean wasNewDbCreated() {
-        return mOpenHelper.wasNewDbCreated();
-    }
-
     public void setLauncherProviderChangeListener(LauncherProviderChangeListener listener) {
         mListener = listener;
         mOpenHelper.mListener = mListener;
@@ -257,17 +252,13 @@
             case LauncherSettings.Settings.METHOD_GET_BOOLEAN: {
                 Bundle result = new Bundle();
                 result.putBoolean(LauncherSettings.Settings.EXTRA_VALUE,
-                        getContext().getSharedPreferences(
-                                LauncherAppState.getSharedPreferencesKey(), Context.MODE_PRIVATE)
-                                .getBoolean(arg, extras.getBoolean(
-                                        LauncherSettings.Settings.EXTRA_DEFAULT_VALUE)));
+                        Utilities.getPrefs(getContext()).getBoolean(arg, extras.getBoolean(
+                                LauncherSettings.Settings.EXTRA_DEFAULT_VALUE)));
                 return result;
             }
             case LauncherSettings.Settings.METHOD_SET_BOOLEAN: {
                 boolean value = extras.getBoolean(LauncherSettings.Settings.EXTRA_VALUE);
-                getContext().getSharedPreferences(
-                        LauncherAppState.getSharedPreferencesKey(), Context.MODE_PRIVATE)
-                        .edit().putBoolean(arg, value).apply();
+                Utilities.getPrefs(getContext()).edit().putBoolean(arg, value).apply();
                 if (mListener != null) {
                     mListener.onSettingsChanged(arg, value);
                 }
@@ -275,6 +266,50 @@
                 result.putBoolean(LauncherSettings.Settings.EXTRA_VALUE, value);
                 return result;
             }
+            case LauncherSettings.Settings.METHOD_CLEAR_EMPTY_DB_FLAG: {
+                clearFlagEmptyDbCreated();
+                return null;
+            }
+            case LauncherSettings.Settings.METHOD_DELETE_EMPTY_FOLDERS: {
+                Bundle result = new Bundle();
+                result.putSerializable(LauncherSettings.Settings.EXTRA_VALUE, deleteEmptyFolders());
+                return result;
+            }
+            case LauncherSettings.Settings.METHOD_NEW_ITEM_ID: {
+                Bundle result = new Bundle();
+                result.putLong(LauncherSettings.Settings.EXTRA_VALUE, mOpenHelper.generateNewItemId());
+                return result;
+            }
+            case LauncherSettings.Settings.METHOD_NEW_SCREEN_ID: {
+                Bundle result = new Bundle();
+                result.putLong(LauncherSettings.Settings.EXTRA_VALUE, mOpenHelper.generateNewScreenId());
+                return result;
+            }
+            case LauncherSettings.Settings.METHOD_CREATE_EMPTY_DB: {
+                createEmptyDB();
+                return null;
+            }
+            case LauncherSettings.Settings.METHOD_LOAD_DEFAULT_FAVORITES: {
+                loadDefaultFavoritesIfNecessary();
+                return null;
+            }
+            case LauncherSettings.Settings.METHOD_MIGRATE_LAUNCHER2_SHORTCUTS: {
+                mOpenHelper.migrateLauncher2Shortcuts(mOpenHelper.getWritableDatabase(),
+                        Uri.parse(getContext().getString(R.string.old_launcher_provider_uri)));
+                return null;
+            }
+            case LauncherSettings.Settings.METHOD_UPDATE_FOLDER_ITEMS_RANK: {
+                mOpenHelper.updateFolderItemsRank(mOpenHelper.getWritableDatabase(), false);
+                return null;
+            }
+            case LauncherSettings.Settings.METHOD_CONVERT_SHORTCUTS_TO_ACTIVITIES: {
+                mOpenHelper.convertShortcutsToLauncherActivities(mOpenHelper.getWritableDatabase());
+                return null;
+            }
+            case LauncherSettings.Settings.METHOD_DELETE_DB: {
+                deleteDatabase();
+                return null;
+            }
         }
         return null;
     }
@@ -283,8 +318,8 @@
      * Deletes any empty folder from the DB.
      * @return Ids of deleted folders.
      */
-    public List<Long> deleteEmptyFolders() {
-        ArrayList<Long> folderIds = new ArrayList<Long>();
+    private ArrayList<Long> deleteEmptyFolders() {
+        ArrayList<Long> folderIds = new ArrayList<>();
         SQLiteDatabase db = mOpenHelper.getWritableDatabase();
         db.beginTransaction();
         try {
@@ -301,7 +336,7 @@
                 folderIds.add(c.getLong(0));
             }
             c.close();
-            if (folderIds.size() > 0) {
+            if (!folderIds.isEmpty()) {
                 db.delete(TABLE_FAVORITES, Utilities.createDbSelectionQuery(
                         LauncherSettings.Favorites._ID, folderIds), null);
             }
@@ -327,27 +362,15 @@
         values.put(LauncherSettings.ChangeLogColumns.MODIFIED, System.currentTimeMillis());
     }
 
-    public long generateNewItemId() {
-        return mOpenHelper.generateNewItemId();
-    }
-
-    public long generateNewScreenId() {
-        return mOpenHelper.generateNewScreenId();
-    }
-
     /**
      * Clears all the data for a fresh start.
      */
-    synchronized public void createEmptyDB() {
+    synchronized private void createEmptyDB() {
         mOpenHelper.createEmptyDB(mOpenHelper.getWritableDatabase());
     }
 
-    public void clearFlagEmptyDbCreated() {
-        String spKey = LauncherAppState.getSharedPreferencesKey();
-        getContext().getSharedPreferences(spKey, Context.MODE_PRIVATE)
-            .edit()
-            .remove(EMPTY_DATABASE_CREATED)
-            .commit();
+    private void clearFlagEmptyDbCreated() {
+        Utilities.getPrefs(getContext()).edit().remove(EMPTY_DATABASE_CREATED).commit();
     }
 
     /**
@@ -357,9 +380,8 @@
      *   3) From a partner configuration APK, already in the system image
      *   4) The default configuration for the particular device
      */
-    synchronized public void loadDefaultFavoritesIfNecessary() {
-        String spKey = LauncherAppState.getSharedPreferencesKey();
-        SharedPreferences sp = getContext().getSharedPreferences(spKey, Context.MODE_PRIVATE);
+    synchronized private void loadDefaultFavoritesIfNecessary() {
+        SharedPreferences sp = Utilities.getPrefs(getContext());
 
         if (sp.getBoolean(EMPTY_DATABASE_CREATED, false)) {
             Log.d(TAG, "loading default workspace");
@@ -443,21 +465,7 @@
                 mOpenHelper, getContext().getResources(), defaultLayout);
     }
 
-    public void migrateLauncher2Shortcuts() {
-        mOpenHelper.migrateLauncher2Shortcuts(mOpenHelper.getWritableDatabase(),
-                Uri.parse(getContext().getString(R.string.old_launcher_provider_uri)));
-    }
-
-    public void updateFolderItemsRank() {
-        mOpenHelper.updateFolderItemsRank(mOpenHelper.getWritableDatabase(), false);
-    }
-
-    public void convertShortcutsToLauncherActivities() {
-        mOpenHelper.convertShortcutsToLauncherActivities(mOpenHelper.getWritableDatabase());
-    }
-
-
-    public void deleteDatabase() {
+    private void deleteDatabase() {
         // Are you sure? (y/n)
         final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
         final File dbFile = new File(db.getPath());
@@ -635,15 +643,11 @@
         }
 
         private void setFlagJustLoadedOldDb() {
-            String spKey = LauncherAppState.getSharedPreferencesKey();
-            SharedPreferences sp = mContext.getSharedPreferences(spKey, Context.MODE_PRIVATE);
-            sp.edit().putBoolean(EMPTY_DATABASE_CREATED, false).commit();
+            Utilities.getPrefs(mContext).edit().putBoolean(EMPTY_DATABASE_CREATED, false).commit();
         }
 
         private void setFlagEmptyDbCreated() {
-            String spKey = LauncherAppState.getSharedPreferencesKey();
-            SharedPreferences sp = mContext.getSharedPreferences(spKey, Context.MODE_PRIVATE);
-            sp.edit().putBoolean(EMPTY_DATABASE_CREATED, true).commit();
+            Utilities.getPrefs(mContext).edit().putBoolean(EMPTY_DATABASE_CREATED, true).commit();
         }
 
         @Override
diff --git a/src/com/android/launcher3/LauncherSettings.java b/src/com/android/launcher3/LauncherSettings.java
index 8a5804f..9ee6a21 100644
--- a/src/com/android/launcher3/LauncherSettings.java
+++ b/src/com/android/launcher3/LauncherSettings.java
@@ -16,7 +16,9 @@
 
 package com.android.launcher3;
 
+import android.content.ContentResolver;
 import android.net.Uri;
+import android.os.Bundle;
 import android.provider.BaseColumns;
 
 import com.android.launcher3.config.ProviderConfig;
@@ -321,8 +323,27 @@
 
         public static final String METHOD_GET_BOOLEAN = "get_boolean_setting";
         public static final String METHOD_SET_BOOLEAN = "set_boolean_setting";
+        public static final String METHOD_CLEAR_EMPTY_DB_FLAG = "clear_empty_db_flag";
+
+        public static final String METHOD_DELETE_EMPTY_FOLDERS = "delete_empty_folders";
+        public static final String METHOD_UPDATE_FOLDER_ITEMS_RANK = "update_folder_items_rank";
+        public static final String METHOD_CONVERT_SHORTCUTS_TO_ACTIVITIES =
+                "convert_shortcuts_to_launcher_activities";
+
+        public static final String METHOD_NEW_ITEM_ID = "generate_new_item_id";
+        public static final String METHOD_NEW_SCREEN_ID = "generate_new_screen_id";
+
+        public static final String METHOD_CREATE_EMPTY_DB = "create_empty_db";
+        public static final String METHOD_DELETE_DB = "delete_db";
+
+        public static final String METHOD_LOAD_DEFAULT_FAVORITES = "load_default_favorites";
+        public static final String METHOD_MIGRATE_LAUNCHER2_SHORTCUTS = "migrate_l2_shortcuts";
 
         public static final String EXTRA_VALUE = "value";
         public static final String EXTRA_DEFAULT_VALUE = "default_value";
+
+        public static Bundle call(ContentResolver cr, String method) {
+            return cr.call(CONTENT_URI, method, null, null);
+        }
     }
 }
diff --git a/src/com/android/launcher3/PageIndicatorMarker.java b/src/com/android/launcher3/PageIndicatorMarker.java
index f012db7..7bf21dd 100644
--- a/src/com/android/launcher3/PageIndicatorMarker.java
+++ b/src/com/android/launcher3/PageIndicatorMarker.java
@@ -45,6 +45,7 @@
     }
 
     protected void onFinishInflate() {
+        super.onFinishInflate();
         mActiveMarker = (ImageView) findViewById(R.id.active);
         mInactiveMarker = (ImageView) findViewById(R.id.inactive);
     }
diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java
index e90ec14..d053d4d 100644
--- a/src/com/android/launcher3/PagedView.java
+++ b/src/com/android/launcher3/PagedView.java
@@ -2047,11 +2047,6 @@
         whichPage = validateNewPage(whichPage);
 
         mNextPage = whichPage;
-        View focusedChild = getFocusedChild();
-        if (focusedChild != null && whichPage != mCurrentPage &&
-                focusedChild == getPageAt(mCurrentPage)) {
-            focusedChild.clearFocus();
-        }
 
         pageBeginMoving();
         awakenScrollBars(duration);
diff --git a/src/com/android/launcher3/ShortcutInfo.java b/src/com/android/launcher3/ShortcutInfo.java
index a86a2f9..db0f845 100644
--- a/src/com/android/launcher3/ShortcutInfo.java
+++ b/src/com/android/launcher3/ShortcutInfo.java
@@ -247,15 +247,6 @@
                 + " user=" + user + ")";
     }
 
-    public static void dumpShortcutInfoList(String tag, String label,
-            ArrayList<ShortcutInfo> list) {
-        Log.d(tag, label + " size=" + list.size());
-        for (ShortcutInfo info: list) {
-            Log.d(tag, "   title=\"" + info.title + " icon=" + info.mIcon
-                    + " customIcon=" + info.customIcon);
-        }
-    }
-
     public ComponentName getTargetComponent() {
         return promisedIntent != null ? promisedIntent.getComponent() : intent.getComponent();
     }
diff --git a/src/com/android/launcher3/Stats.java b/src/com/android/launcher3/Stats.java
index 4aba150..59feeb7 100644
--- a/src/com/android/launcher3/Stats.java
+++ b/src/com/android/launcher3/Stats.java
@@ -33,7 +33,7 @@
      * Implemented by containers to provide a launch source for a given child.
      */
     public interface LaunchSourceProvider {
-        void fillInLaunchSourceData(Bundle sourceData);
+        void fillInLaunchSourceData(View v, Bundle sourceData);
     }
 
     /**
@@ -72,7 +72,7 @@
             }
 
             if (provider != null) {
-                provider.fillInLaunchSourceData(sourceData);
+                provider.fillInLaunchSourceData(v, sourceData);
             } else if (ProviderConfig.IS_DOGFOOD_BUILD) {
                 throw new RuntimeException("Expected LaunchSourceProvider");
             }
diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java
index eef7a41..9c81284 100644
--- a/src/com/android/launcher3/Utilities.java
+++ b/src/com/android/launcher3/Utilities.java
@@ -59,6 +59,7 @@
 import android.view.View;
 import android.widget.Toast;
 
+import com.android.launcher3.compat.UserHandleCompat;
 import com.android.launcher3.config.ProviderConfig;
 
 import java.io.ByteArrayOutputStream;
@@ -139,9 +140,8 @@
     }
 
     public static boolean isAllowRotationPrefEnabled(Context context) {
-        SharedPreferences sharedPrefs = context.getSharedPreferences(
-                LauncherAppState.getSharedPreferencesKey(), Context.MODE_PRIVATE);
-        boolean allowRotationPref = sharedPrefs.getBoolean(ALLOW_ROTATION_PREFERENCE_KEY, false);
+        boolean allowRotationPref = getPrefs(context)
+                .getBoolean(ALLOW_ROTATION_PREFERENCE_KEY, false);
         return sForceEnableRotation || allowRotationPref;
     }
 
@@ -208,6 +208,28 @@
     }
 
     /**
+     * Returns a bitmap suitable for the all apps view. The icon is badged for {@param user}
+     */
+    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
+    public static Bitmap createBadgedIconBitmap(
+            Drawable icon, UserHandleCompat user, Context context) {
+        Bitmap bitmap = createIconBitmap(icon, context);
+        if (Utilities.ATLEAST_LOLLIPOP && user != null
+                && !UserHandleCompat.myUserHandle().equals(user)) {
+            BitmapDrawable drawable = new BitmapDrawable(context.getResources(), bitmap);
+            Drawable badged = context.getPackageManager().getUserBadgedIcon(
+                    drawable, user.getUser());
+            if (badged instanceof BitmapDrawable) {
+                return ((BitmapDrawable) badged).getBitmap();
+            } else {
+                return createIconBitmap(badged, context);
+            }
+        } else {
+            return bitmap;
+        }
+    }
+
+    /**
      * Returns a bitmap suitable for the all apps view.
      */
     public static Bitmap createIconBitmap(Drawable icon, Context context) {
@@ -778,4 +800,9 @@
     public static int longCompare(long lhs, long rhs) {
         return lhs < rhs ? -1 : (lhs == rhs ? 0 : 1);
     }
+
+    public static SharedPreferences getPrefs(Context context) {
+        return context.getSharedPreferences(
+                LauncherFiles.SHARED_PREFERENCES_KEY, Context.MODE_PRIVATE);
+    }
 }
diff --git a/src/com/android/launcher3/WidgetPreviewLoader.java b/src/com/android/launcher3/WidgetPreviewLoader.java
index 603b072..10c1053 100644
--- a/src/com/android/launcher3/WidgetPreviewLoader.java
+++ b/src/com/android/launcher3/WidgetPreviewLoader.java
@@ -428,8 +428,9 @@
             float iconScale = Math.min((float) smallestSide / (appIconSize + 2 * minOffset), scale);
 
             try {
-                Drawable icon = mutateOnMainThread(mManager.loadIcon(info, mIconCache));
+                Drawable icon = mManager.loadIcon(info, mIconCache);
                 if (icon != null) {
+                    icon = mutateOnMainThread(icon);
                     int hoffset = (int) ((tileW - appIconSize * iconScale) / 2) + x;
                     int yoffset = (int) ((tileH - appIconSize * iconScale) / 2);
                     icon.setBounds(hoffset, yoffset,
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 2bedb9f..0eac09d 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -29,7 +29,6 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.res.Resources;
-import android.content.res.TypedArray;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.Paint;
@@ -59,7 +58,6 @@
 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.UninstallDropTarget.UninstallSource;
 import com.android.launcher3.accessibility.LauncherAccessibilityDelegate;
 import com.android.launcher3.accessibility.LauncherAccessibilityDelegate.AccessibilityDragSource;
@@ -74,6 +72,7 @@
 import com.android.launcher3.dragndrop.SpringLoadedDragController;
 import com.android.launcher3.util.LongArrayMap;
 import com.android.launcher3.util.Thunk;
+import com.android.launcher3.util.WallpaperOffsetInterpolator;
 import com.android.launcher3.util.WallpaperUtils;
 import com.android.launcher3.widget.PendingAddShortcutInfo;
 import com.android.launcher3.widget.PendingAddWidgetInfo;
@@ -114,7 +113,6 @@
 
     private LayoutTransition mLayoutTransition;
     @Thunk final WallpaperManager mWallpaperManager;
-    @Thunk IBinder mWindowToken;
 
     private ShortcutAndWidgetContainer mDragSourceInternal;
 
@@ -209,10 +207,7 @@
     public static final int DRAG_BITMAP_PADDING = 2;
     private boolean mWorkspaceFadeInAdjacentScreens;
 
-    WallpaperOffsetInterpolator mWallpaperOffset;
-    @Thunk boolean mWallpaperIsLiveWallpaper;
-    @Thunk int mNumPagesForWallpaperParallax;
-    @Thunk float mLastSetWallpaperOffsetSteps = 0;
+    final WallpaperOffsetInterpolator mWallpaperOffset;
 
     @Thunk Runnable mDelayedResizeRunnable;
     private Runnable mDelayedSnapToPageRunnable;
@@ -306,6 +301,8 @@
         mFadeInAdjacentScreens = false;
         mWallpaperManager = WallpaperManager.getInstance(context);
 
+        mWallpaperOffset = new WallpaperOffsetInterpolator(this);
+
         mSpringLoadedShrinkFactor =
                 res.getInteger(R.integer.config_workspaceSpringLoadShrinkPercentage) / 100.0f;
         mOverviewModeShrinkFactor =
@@ -428,8 +425,6 @@
         setMinScale(mOverviewModeShrinkFactor);
         setupLayoutTransition();
 
-        mWallpaperOffset = new WallpaperOffsetInterpolator();
-
         mMaxDistanceForFolderCreation = (0.55f * grid.iconSizePx);
 
         // Set the wallpaper dimensions when Launcher starts up
@@ -799,7 +794,9 @@
         mWorkspaceScreens.remove(EXTRA_EMPTY_SCREEN_ID);
         mScreenOrder.remove(EXTRA_EMPTY_SCREEN_ID);
 
-        long newId = LauncherAppState.getLauncherProvider().generateNewScreenId();
+        long newId = LauncherSettings.Settings.call(getContext().getContentResolver(),
+                LauncherSettings.Settings.METHOD_NEW_SCREEN_ID)
+                .getLong(LauncherSettings.Settings.EXTRA_VALUE);
         mWorkspaceScreens.put(newId, cl);
         mScreenOrder.add(newId);
 
@@ -815,8 +812,7 @@
     }
 
     public CellLayout getScreenWithId(long screenId) {
-        CellLayout layout = mWorkspaceScreens.get(screenId);
-        return layout;
+        return mWorkspaceScreens.get(screenId);
     }
 
     public long getIdForScreen(CellLayout layout) {
@@ -1327,191 +1323,6 @@
         snapToPage(getPageIndexForScreenId(screenId), r);
     }
 
-    class WallpaperOffsetInterpolator implements Choreographer.FrameCallback {
-        float mFinalOffset = 0.0f;
-        float mCurrentOffset = 0.5f; // to force an initial update
-        boolean mWaitingForUpdate;
-        Choreographer mChoreographer;
-        Interpolator mInterpolator;
-        boolean mAnimating;
-        long mAnimationStartTime;
-        float mAnimationStartOffset;
-        private final int ANIMATION_DURATION = 250;
-        // Don't use all the wallpaper for parallax until you have at least this many pages
-        private final int MIN_PARALLAX_PAGE_SPAN = 3;
-        int mNumScreens;
-
-        public WallpaperOffsetInterpolator() {
-            mChoreographer = Choreographer.getInstance();
-            mInterpolator = new DecelerateInterpolator(1.5f);
-        }
-
-        @Override
-        public void doFrame(long frameTimeNanos) {
-            updateOffset(false);
-        }
-
-        private void updateOffset(boolean force) {
-            if (mWaitingForUpdate || force) {
-                mWaitingForUpdate = false;
-                if (computeScrollOffset() && mWindowToken != null) {
-                    try {
-                        mWallpaperManager.setWallpaperOffsets(mWindowToken,
-                                mWallpaperOffset.getCurrX(), 0.5f);
-                        setWallpaperOffsetSteps();
-                    } catch (IllegalArgumentException e) {
-                        Log.e(TAG, "Error updating wallpaper offset: " + e);
-                    }
-                }
-            }
-        }
-
-        public boolean computeScrollOffset() {
-            final float oldOffset = mCurrentOffset;
-            if (mAnimating) {
-                long durationSinceAnimation = System.currentTimeMillis() - mAnimationStartTime;
-                float t0 = durationSinceAnimation / (float) ANIMATION_DURATION;
-                float t1 = mInterpolator.getInterpolation(t0);
-                mCurrentOffset = mAnimationStartOffset +
-                        (mFinalOffset - mAnimationStartOffset) * t1;
-                mAnimating = durationSinceAnimation < ANIMATION_DURATION;
-            } else {
-                mCurrentOffset = mFinalOffset;
-            }
-
-            if (Math.abs(mCurrentOffset - mFinalOffset) > 0.0000001f) {
-                scheduleUpdate();
-            }
-            if (Math.abs(oldOffset - mCurrentOffset) > 0.0000001f) {
-                return true;
-            }
-            return false;
-        }
-
-        public float wallpaperOffsetForScroll(int scroll) {
-            // TODO: do different behavior if it's  a live wallpaper?
-            // Don't use up all the wallpaper parallax until you have at least
-            // MIN_PARALLAX_PAGE_SPAN pages
-            int numScrollingPages = getNumScreensExcludingEmptyAndCustom();
-            int parallaxPageSpan;
-            if (mWallpaperIsLiveWallpaper) {
-                parallaxPageSpan = numScrollingPages - 1;
-            } else {
-                parallaxPageSpan = Math.max(MIN_PARALLAX_PAGE_SPAN, numScrollingPages - 1);
-            }
-            mNumPagesForWallpaperParallax = parallaxPageSpan;
-
-            if (getChildCount() <= 1) {
-                if (mIsRtl) {
-                    return 1 - 1.0f/mNumPagesForWallpaperParallax;
-                }
-                return 0;
-            }
-
-            // Exclude the leftmost page
-            int emptyExtraPages = numEmptyScreensToIgnore();
-            int firstIndex = numCustomPages();
-            // Exclude the last extra empty screen (if we have > MIN_PARALLAX_PAGE_SPAN pages)
-            int lastIndex = getChildCount() - 1 - emptyExtraPages;
-            if (mIsRtl) {
-                int temp = firstIndex;
-                firstIndex = lastIndex;
-                lastIndex = temp;
-            }
-
-            int firstPageScrollX = getScrollForPage(firstIndex);
-            int scrollRange = getScrollForPage(lastIndex) - firstPageScrollX;
-            if (scrollRange == 0) {
-                return 0;
-            } else {
-                // Sometimes the left parameter of the pages is animated during a layout transition;
-                // this parameter offsets it to keep the wallpaper from animating as well
-                int adjustedScroll =
-                        scroll - firstPageScrollX - getLayoutTransitionOffsetForPage(0);
-                float offset = Math.min(1, adjustedScroll / (float) scrollRange);
-                offset = Math.max(0, offset);
-
-                // On RTL devices, push the wallpaper offset to the right if we don't have enough
-                // pages (ie if numScrollingPages < MIN_PARALLAX_PAGE_SPAN)
-                if (!mWallpaperIsLiveWallpaper && numScrollingPages < MIN_PARALLAX_PAGE_SPAN
-                        && mIsRtl) {
-                    return offset * (parallaxPageSpan - numScrollingPages + 1) / parallaxPageSpan;
-                }
-                return offset * (numScrollingPages - 1) / parallaxPageSpan;
-            }
-        }
-
-        private float wallpaperOffsetForCurrentScroll() {
-            return wallpaperOffsetForScroll(getScrollX());
-        }
-
-        private int numEmptyScreensToIgnore() {
-            int numScrollingPages = getChildCount() - numCustomPages();
-            if (numScrollingPages >= MIN_PARALLAX_PAGE_SPAN && hasExtraEmptyScreen()) {
-                return 1;
-            } else {
-                return 0;
-            }
-        }
-
-        private int getNumScreensExcludingEmptyAndCustom() {
-            int numScrollingPages = getChildCount() - numEmptyScreensToIgnore() - numCustomPages();
-            return numScrollingPages;
-        }
-
-        public void syncWithScroll() {
-            float offset = wallpaperOffsetForCurrentScroll();
-            mWallpaperOffset.setFinalX(offset);
-            updateOffset(true);
-        }
-
-        public float getCurrX() {
-            return mCurrentOffset;
-        }
-
-        public float getFinalX() {
-            return mFinalOffset;
-        }
-
-        private void animateToFinal() {
-            mAnimating = true;
-            mAnimationStartOffset = mCurrentOffset;
-            mAnimationStartTime = System.currentTimeMillis();
-        }
-
-        private void setWallpaperOffsetSteps() {
-            // Set wallpaper offset steps (1 / (number of screens - 1))
-            float xOffset = 1.0f / mNumPagesForWallpaperParallax;
-            if (xOffset != mLastSetWallpaperOffsetSteps) {
-                mWallpaperManager.setWallpaperOffsetSteps(xOffset, 1.0f);
-                mLastSetWallpaperOffsetSteps = xOffset;
-            }
-        }
-
-        public void setFinalX(float x) {
-            scheduleUpdate();
-            mFinalOffset = Math.max(0f, Math.min(x, 1.0f));
-            if (getNumScreensExcludingEmptyAndCustom() != mNumScreens) {
-                if (mNumScreens > 0) {
-                    // Don't animate if we're going from 0 screens
-                    animateToFinal();
-                }
-                mNumScreens = getNumScreensExcludingEmptyAndCustom();
-            }
-        }
-
-        private void scheduleUpdate() {
-            if (!mWaitingForUpdate) {
-                mChoreographer.postFrameCallback(this);
-                mWaitingForUpdate = true;
-            }
-        }
-
-        public void jumpToFinal() {
-            mCurrentOffset = mFinalOffset;
-        }
-    }
-
     @Override
     public void computeScroll() {
         super.computeScroll();
@@ -1532,18 +1343,6 @@
         }
     }
 
-    float backgroundAlphaInterpolator(float r) {
-        float pivotA = 0.1f;
-        float pivotB = 0.4f;
-        if (r < pivotA) {
-            return 0;
-        } else if (r > pivotB) {
-            return 1.0f;
-        } else {
-            return (r - pivotA)/(pivotB - pivotA);
-        }
-    }
-
     private void updatePageAlphaValues(int screenCenter) {
         if (mWorkspaceFadeInAdjacentScreens &&
                 !workspaceInModalState() &&
@@ -1647,13 +1446,12 @@
         if (!am.isTouchExplorationEnabled()) {
             return null;
         }
-        OnClickListener listener = new OnClickListener() {
+        return new OnClickListener() {
             @Override
             public void onClick(View arg0) {
                 mLauncher.showOverviewMode(true);
             }
         };
-        return listener;
     }
 
     @Override
@@ -1665,14 +1463,15 @@
 
     protected void onAttachedToWindow() {
         super.onAttachedToWindow();
-        mWindowToken = getWindowToken();
+        IBinder windowToken = getWindowToken();
+        mWallpaperOffset.setWindowToken(windowToken);
         computeScroll();
-        mDragController.setWindowToken(mWindowToken);
+        mDragController.setWindowToken(windowToken);
     }
 
     protected void onDetachedFromWindow() {
         super.onDetachedFromWindow();
-        mWindowToken = null;
+        mWallpaperOffset.setWindowToken(null);
     }
 
     protected void onResume() {
@@ -1690,10 +1489,7 @@
         if (LauncherAppState.getInstance().hasWallpaperChangedSinceLastCheck()) {
             setWallpaperDimension();
         }
-        mWallpaperIsLiveWallpaper = mWallpaperManager.getWallpaperInfo() != null;
-        // Force the wallpaper offset steps to be set again, because another app might have changed
-        // them
-        mLastSetWallpaperOffsetSteps = 0f;
+        mWallpaperOffset.onResume();
     }
 
     @Override
@@ -2064,6 +1860,7 @@
     @Override
     public void onLauncherTransitionPrepare(Launcher l, boolean animated, boolean toWorkspace) {
         mIsSwitchingState = true;
+        mTransitionProgress = 0;
 
         // Invalidate here to ensure that the pages are rendered during the state change transition.
         invalidate();
@@ -2816,19 +2613,6 @@
                 (int) (mTempXY[1] + scale * boundingLayout.getMeasuredHeight()));
     }
 
-    public void getViewLocationRelativeToSelf(View v, int[] location) {
-        getLocationInWindow(location);
-        int x = location[0];
-        int y = location[1];
-
-        v.getLocationInWindow(location);
-        int vX = location[0];
-        int vY = location[1];
-
-        location[0] = vX - x;
-        location[1] = vY - y;
-    }
-
     @Override
     public void onDragEnter(DragObject d) {
         if (ENFORCE_DRAG_EVENT_ORDER) {
@@ -3574,11 +3358,6 @@
         Resources res = mLauncher.getResources();
         final int duration = res.getInteger(R.integer.config_dropAnimMaxDuration) - 200;
 
-        // In the case where we've prebound the widget, we remove it from the DragLayer
-        if (finalView instanceof AppWidgetHostView && external) {
-            mLauncher.getDragLayer().removeView(finalView);
-        }
-
         boolean isWidget = info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET ||
                 info.itemType == LauncherSettings.Favorites.ITEM_TYPE_CUSTOM_APPWIDGET;
         if ((animationType == ANIMATE_INTO_POSITION_AND_RESIZE || external) && finalView != null) {
@@ -3754,47 +3533,6 @@
         }
     }
 
-    void saveWorkspaceToDb() {
-        saveWorkspaceScreenToDb((CellLayout) mLauncher.getHotseat().getLayout());
-        int count = getChildCount();
-        for (int i = 0; i < count; i++) {
-            CellLayout cl = (CellLayout) getChildAt(i);
-            saveWorkspaceScreenToDb(cl);
-        }
-    }
-
-    void saveWorkspaceScreenToDb(CellLayout cl) {
-        int count = cl.getShortcutsAndWidgets().getChildCount();
-
-        long screenId = getIdForScreen(cl);
-        int container = Favorites.CONTAINER_DESKTOP;
-
-        Hotseat hotseat = mLauncher.getHotseat();
-        if (mLauncher.isHotseatLayout(cl)) {
-            screenId = -1;
-            container = Favorites.CONTAINER_HOTSEAT;
-        }
-
-        for (int i = 0; i < count; i++) {
-            View v = cl.getShortcutsAndWidgets().getChildAt(i);
-            ItemInfo info = (ItemInfo) v.getTag();
-            // Null check required as the AllApps button doesn't have an item info
-            if (info != null) {
-                int cellX = info.cellX;
-                int cellY = info.cellY;
-                if (container == Favorites.CONTAINER_HOTSEAT) {
-                    cellX = hotseat.getCellXFromOrder((int) info.screenId);
-                    cellY = hotseat.getCellYFromOrder((int) info.screenId);
-                }
-                LauncherModel.addItemToDatabase(mLauncher, info, container, screenId, cellX, cellY);
-            }
-            if (v instanceof FolderIcon) {
-                FolderIcon fi = (FolderIcon) v;
-                fi.getFolder().addItemLocationsInDatabase();
-            }
-        }
-    }
-
     @Override
     public float getIntrinsicIconScaleFactor() {
         return 1f;
@@ -4392,12 +4130,8 @@
                 page + 1 - delta, nScreens);
     }
 
-    public void getLocationInDragLayer(int[] loc) {
-        mLauncher.getDragLayer().getLocationInDragLayer(this, loc);
-    }
-
     @Override
-    public void fillInLaunchSourceData(Bundle sourceData) {
+    public void fillInLaunchSourceData(View v, Bundle sourceData) {
         sourceData.putString(Stats.SOURCE_EXTRA_CONTAINER, Stats.CONTAINER_HOMESCREEN);
         sourceData.putInt(Stats.SOURCE_EXTRA_CONTAINER_PAGE, getCurrentPage());
     }
diff --git a/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java b/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java
index f5db6c0..03731d1 100644
--- a/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java
+++ b/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java
@@ -172,7 +172,7 @@
             return true;
         } else if (action == MOVE_TO_WORKSPACE) {
             Folder folder = mLauncher.getWorkspace().getOpenFolder();
-            mLauncher.closeFolder(folder);
+            mLauncher.closeFolder(folder, true);
             ShortcutInfo info = (ShortcutInfo) item;
             folder.getInfo().remove(info);
 
diff --git a/src/com/android/launcher3/allapps/AllAppsFastScrollHelper.java b/src/com/android/launcher3/allapps/AllAppsFastScrollHelper.java
index 1045342..73de45e 100644
--- a/src/com/android/launcher3/allapps/AllAppsFastScrollHelper.java
+++ b/src/com/android/launcher3/allapps/AllAppsFastScrollHelper.java
@@ -27,7 +27,7 @@
 
 public class AllAppsFastScrollHelper implements AllAppsGridAdapter.BindViewCallback {
 
-    private static final int INITIAL_TOUCH_SETTLING_DURATION = 300;
+    private static final int INITIAL_TOUCH_SETTLING_DURATION = 100;
     private static final int REPEAT_TOUCH_SETTLING_DURATION = 200;
     private static final float FAST_SCROLL_TOUCH_VELOCITY_BARRIER = 1900f;
 
@@ -219,7 +219,9 @@
         FastBitmapDrawable.State newState = FastBitmapDrawable.State.NORMAL;
         if (mCurrentFastScrollSection != null && pos > -1) {
             AlphabeticalAppsList.AdapterItem item = mApps.getAdapterItems().get(pos);
-            newState = item.sectionName.equals(mCurrentFastScrollSection) ?
+            boolean highlight = item.sectionName.equals(mCurrentFastScrollSection) &&
+                    item.position == mTargetFastScrollPosition;
+            newState = highlight ?
                     FastBitmapDrawable.State.FAST_SCROLL_HIGHLIGHTED :
                     FastBitmapDrawable.State.FAST_SCROLL_UNHIGHLIGHTED;
         }
diff --git a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
index 48b9494..1cb03c9 100644
--- a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
@@ -25,6 +25,7 @@
 import android.view.View;
 
 import com.android.launcher3.BaseRecyclerView;
+import com.android.launcher3.BubbleTextView;
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.R;
 import com.android.launcher3.Stats;
@@ -155,12 +156,25 @@
     }
 
     @Override
-    public void fillInLaunchSourceData(Bundle sourceData) {
+    public void fillInLaunchSourceData(View v, Bundle sourceData) {
         sourceData.putString(Stats.SOURCE_EXTRA_CONTAINER, Stats.CONTAINER_ALL_APPS);
         if (mApps.hasFilter()) {
             sourceData.putString(Stats.SOURCE_EXTRA_SUB_CONTAINER,
                     Stats.SUB_CONTAINER_ALL_APPS_SEARCH);
         } else {
+            if (v instanceof BubbleTextView) {
+                BubbleTextView icon = (BubbleTextView) v;
+                int position = getChildPosition(icon);
+                if (position != NO_POSITION) {
+                    List<AlphabeticalAppsList.AdapterItem> items = mApps.getAdapterItems();
+                    AlphabeticalAppsList.AdapterItem item = items.get(position);
+                    if (item.viewType == AllAppsGridAdapter.PREDICTION_ICON_VIEW_TYPE) {
+                        sourceData.putString(Stats.SOURCE_EXTRA_SUB_CONTAINER,
+                                Stats.SUB_CONTAINER_ALL_APPS_PREDICTION);
+                        return;
+                    }
+                }
+            }
             sourceData.putString(Stats.SOURCE_EXTRA_SUB_CONTAINER,
                     Stats.SUB_CONTAINER_ALL_APPS_A_Z);
         }
diff --git a/src/com/android/launcher3/compat/LauncherActivityInfoCompat.java b/src/com/android/launcher3/compat/LauncherActivityInfoCompat.java
index 07ef0ef..0bc9588 100644
--- a/src/com/android/launcher3/compat/LauncherActivityInfoCompat.java
+++ b/src/com/android/launcher3/compat/LauncherActivityInfoCompat.java
@@ -33,7 +33,6 @@
     public abstract Drawable getIcon(int density);
     public abstract ApplicationInfo getApplicationInfo();
     public abstract long getFirstInstallTime();
-    public abstract Drawable getBadgedIcon(int density);
 
     /**
      * Creates a LauncherActivityInfoCompat for the primary user.
diff --git a/src/com/android/launcher3/compat/LauncherActivityInfoCompatV16.java b/src/com/android/launcher3/compat/LauncherActivityInfoCompatV16.java
index ea51aac..fee0376 100644
--- a/src/com/android/launcher3/compat/LauncherActivityInfoCompatV16.java
+++ b/src/com/android/launcher3/compat/LauncherActivityInfoCompatV16.java
@@ -93,8 +93,4 @@
     public String getName() {
         return mActivityInfo.name;
     }
-
-    public Drawable getBadgedIcon(int density) {
-        return getIcon(density);
-    }
 }
diff --git a/src/com/android/launcher3/compat/LauncherActivityInfoCompatVL.java b/src/com/android/launcher3/compat/LauncherActivityInfoCompatVL.java
index 4448758..67c5c27 100644
--- a/src/com/android/launcher3/compat/LauncherActivityInfoCompatVL.java
+++ b/src/com/android/launcher3/compat/LauncherActivityInfoCompatVL.java
@@ -55,8 +55,4 @@
     public long getFirstInstallTime() {
         return mLauncherActivityInfo.getFirstInstallTime();
     }
-
-    public Drawable getBadgedIcon(int density) {
-        return mLauncherActivityInfo.getBadgedIcon(density);
-    }
 }
diff --git a/src/com/android/launcher3/compat/UserHandleCompat.java b/src/com/android/launcher3/compat/UserHandleCompat.java
index 567022b..9479908 100644
--- a/src/com/android/launcher3/compat/UserHandleCompat.java
+++ b/src/com/android/launcher3/compat/UserHandleCompat.java
@@ -49,7 +49,7 @@
         }
     }
 
-    UserHandle getUser() {
+    public UserHandle getUser() {
         return mUser;
     }
 
diff --git a/src/com/android/launcher3/compat/UserManagerCompat.java b/src/com/android/launcher3/compat/UserManagerCompat.java
index f708004..6b7cba8 100644
--- a/src/com/android/launcher3/compat/UserManagerCompat.java
+++ b/src/com/android/launcher3/compat/UserManagerCompat.java
@@ -17,8 +17,6 @@
 package com.android.launcher3.compat;
 
 import android.content.Context;
-import android.graphics.drawable.Drawable;
-import android.os.Build;
 
 import com.android.launcher3.Utilities;
 
@@ -54,7 +52,6 @@
     public abstract List<UserHandleCompat> getUserProfiles();
     public abstract long getSerialNumberForUser(UserHandleCompat user);
     public abstract UserHandleCompat getUserForSerialNumber(long serialNumber);
-    public abstract Drawable getBadgedDrawableForUser(Drawable unbadged, UserHandleCompat user);
     public abstract CharSequence getBadgedLabelForUser(CharSequence label, UserHandleCompat user);
     public abstract long getUserCreationTime(UserHandleCompat user);
 }
diff --git a/src/com/android/launcher3/compat/UserManagerCompatV16.java b/src/com/android/launcher3/compat/UserManagerCompatV16.java
index 85aee57..fcd7555 100644
--- a/src/com/android/launcher3/compat/UserManagerCompatV16.java
+++ b/src/com/android/launcher3/compat/UserManagerCompatV16.java
@@ -16,8 +16,6 @@
 
 package com.android.launcher3.compat;
 
-import android.graphics.drawable.Drawable;
-
 import java.util.ArrayList;
 import java.util.List;
 
@@ -36,11 +34,6 @@
         return UserHandleCompat.myUserHandle();
     }
 
-    public Drawable getBadgedDrawableForUser(Drawable unbadged,
-            UserHandleCompat user) {
-        return unbadged;
-    }
-
     public long getSerialNumberForUser(UserHandleCompat user) {
         return 0;
     }
diff --git a/src/com/android/launcher3/compat/UserManagerCompatVL.java b/src/com/android/launcher3/compat/UserManagerCompatVL.java
index dc3ec3c..c53d702 100644
--- a/src/com/android/launcher3/compat/UserManagerCompatVL.java
+++ b/src/com/android/launcher3/compat/UserManagerCompatVL.java
@@ -21,11 +21,9 @@
 import android.content.Context;
 import android.content.SharedPreferences;
 import android.content.pm.PackageManager;
-import android.graphics.drawable.Drawable;
 import android.os.Build;
 import android.os.UserHandle;
 
-import com.android.launcher3.LauncherAppState;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.util.LongArrayMap;
 
@@ -87,11 +85,6 @@
     }
 
     @Override
-    public Drawable getBadgedDrawableForUser(Drawable unbadged, UserHandleCompat user) {
-        return mPm.getUserBadgedIcon(unbadged, user.getUser());
-    }
-
-    @Override
     public CharSequence getBadgedLabelForUser(CharSequence label, UserHandleCompat user) {
         if (user == null) {
             return label;
@@ -104,8 +97,7 @@
         if (Utilities.ATLEAST_MARSHMALLOW) {
             return mUserManager.getUserCreationTime(user.getUser());
         }
-        SharedPreferences prefs = mContext.getSharedPreferences(
-                LauncherAppState.getSharedPreferencesKey(), Context.MODE_PRIVATE);
+        SharedPreferences prefs = Utilities.getPrefs(mContext);
         String key = USER_CREATION_TIME_KEY + getSerialNumberForUser(user);
         if (!prefs.contains(key)) {
             prefs.edit().putLong(key, System.currentTimeMillis()).apply();
diff --git a/src/com/android/launcher3/dragndrop/DragController.java b/src/com/android/launcher3/dragndrop/DragController.java
index a4bd753..d61117c 100644
--- a/src/com/android/launcher3/dragndrop/DragController.java
+++ b/src/com/android/launcher3/dragndrop/DragController.java
@@ -166,11 +166,9 @@
      * @param bmp The bitmap that represents the view being dragged
      * @param source An object representing where the drag originated
      * @param dragInfo The data associated with the object that is being dragged
+     * @param viewImageBounds the position of the image inside the view
      * @param dragAction The drag action: either {@link #DRAG_ACTION_MOVE} or
      *        {@link #DRAG_ACTION_COPY}
-     * @param viewImageBounds the position of the image inside the view
-     * @param dragRegion Coordinates within the bitmap b for the position of item being dragged.
-     *          Makes dragging feel more precise, e.g. you can clip out a transparent border
      */
     public void startDrag(View v, Bitmap bmp, DragSource source, ItemInfo dragInfo,
             Rect viewImageBounds, int dragAction, float initialDragViewScale) {
@@ -269,44 +267,6 @@
     }
 
     /**
-     * Draw the view into a bitmap.
-     */
-    Bitmap getViewBitmap(View v) {
-        v.clearFocus();
-        v.setPressed(false);
-
-        boolean willNotCache = v.willNotCacheDrawing();
-        v.setWillNotCacheDrawing(false);
-
-        // Reset the drawing cache background color to fully transparent
-        // for the duration of this operation
-        int color = v.getDrawingCacheBackgroundColor();
-        v.setDrawingCacheBackgroundColor(0);
-        float alpha = v.getAlpha();
-        v.setAlpha(1.0f);
-
-        if (color != 0) {
-            v.destroyDrawingCache();
-        }
-        v.buildDrawingCache();
-        Bitmap cacheBitmap = v.getDrawingCache();
-        if (cacheBitmap == null) {
-            Log.e(TAG, "failed getViewBitmap(" + v + ")", new RuntimeException());
-            return null;
-        }
-
-        Bitmap bitmap = Bitmap.createBitmap(cacheBitmap);
-
-        // Restore the view
-        v.destroyDrawingCache();
-        v.setAlpha(alpha);
-        v.setWillNotCacheDrawing(willNotCache);
-        v.setDrawingCacheBackgroundColor(color);
-
-        return bitmap;
-    }
-
-    /**
      * Call this from a drag source view like this:
      *
      * <pre>
diff --git a/src/com/android/launcher3/model/MigrateFromRestoreTask.java b/src/com/android/launcher3/model/MigrateFromRestoreTask.java
index 6a529f6..9cabc8d 100644
--- a/src/com/android/launcher3/model/MigrateFromRestoreTask.java
+++ b/src/com/android/launcher3/model/MigrateFromRestoreTask.java
@@ -71,7 +71,7 @@
     public MigrateFromRestoreTask(Context context) {
         mContext = context;
 
-        SharedPreferences prefs = prefs(context);
+        SharedPreferences prefs = Utilities.getPrefs(context);
         Point sourceSize = parsePoint(prefs.getString(KEY_MIGRATION_SOURCE_SIZE, ""));
         mSrcX = sourceSize.x;
         mSrcY = sourceSize.y;
@@ -135,7 +135,10 @@
                         new boolean[mTrgX][mTrgY], deepCopy(mCarryOver), true);
                 placement.find();
                 if (placement.finalPlacedItems.size() > 0) {
-                    long newScreenId = LauncherAppState.getLauncherProvider().generateNewScreenId();
+                    long newScreenId = LauncherSettings.Settings.call(
+                            mContext.getContentResolver(),
+                            LauncherSettings.Settings.METHOD_NEW_SCREEN_ID)
+                            .getLong(LauncherSettings.Settings.EXTRA_VALUE);
                     allScreens.add(newScreenId);
                     for (DbEntry item : placement.finalPlacedItems) {
                         if (!mCarryOver.remove(itemMap.get(item.id))) {
@@ -632,9 +635,9 @@
                mEntryToRemove.add(entry.id);
                continue;
            }
-
            entries.add(entry);
        }
+       c.close();
        return entries;
     }
 
@@ -655,7 +658,7 @@
                 mEntryToRemove.add(c.getLong(0));
             }
         }
-
+        c.close();
         return total;
     }
 
@@ -745,23 +748,19 @@
 
     public static void markForMigration(Context context, int srcX, int srcY,
             HashSet<String> widgets) {
-        prefs(context).edit()
+        Utilities.getPrefs(context).edit()
                 .putString(KEY_MIGRATION_SOURCE_SIZE, srcX + "," + srcY)
                 .putStringSet(KEY_MIGRATION_WIDGET_MINSIZE, widgets)
                 .apply();
     }
 
     public static boolean shouldRunTask(Context context) {
-        return !TextUtils.isEmpty(prefs(context).getString(KEY_MIGRATION_SOURCE_SIZE, ""));
+        return !TextUtils.isEmpty(Utilities.getPrefs(context).getString(KEY_MIGRATION_SOURCE_SIZE, ""));
     }
 
     public static void clearFlags(Context context) {
-        prefs(context).edit().remove(KEY_MIGRATION_SOURCE_SIZE)
+        Utilities.getPrefs(context).edit().remove(KEY_MIGRATION_SOURCE_SIZE)
                 .remove(KEY_MIGRATION_WIDGET_MINSIZE).commit();
     }
 
-    private static SharedPreferences prefs(Context context) {
-        return context.getSharedPreferences(LauncherAppState.getSharedPreferencesKey(),
-                Context.MODE_PRIVATE);
-    }
 }
diff --git a/src/com/android/launcher3/testing/LauncherExtension.java b/src/com/android/launcher3/testing/LauncherExtension.java
index 8055b5f..8982176 100644
--- a/src/com/android/launcher3/testing/LauncherExtension.java
+++ b/src/com/android/launcher3/testing/LauncherExtension.java
@@ -253,6 +253,11 @@
         }
 
         @Override
+        public Bundle getAdditionalSearchWidgetOptions() {
+            return new Bundle();
+        }
+
+        @Override
         public Intent getFirstRunActivity() {
             return null;
         }
diff --git a/src/com/android/launcher3/testing/ToggleWeightWatcher.java b/src/com/android/launcher3/testing/ToggleWeightWatcher.java
index 15e55ee..e08ec3a 100644
--- a/src/com/android/launcher3/testing/ToggleWeightWatcher.java
+++ b/src/com/android/launcher3/testing/ToggleWeightWatcher.java
@@ -1,13 +1,13 @@
 package com.android.launcher3.testing;
 
 import android.app.Activity;
-import android.content.Context;
 import android.content.SharedPreferences;
 import android.os.Bundle;
 import android.view.View;
 
 import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherAppState;
+import com.android.launcher3.Utilities;
 import com.android.launcher3.util.TestingUtils;
 
 public class ToggleWeightWatcher extends Activity {
@@ -16,8 +16,7 @@
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
-        String spKey = LauncherAppState.getSharedPreferencesKey();
-        SharedPreferences sp = getSharedPreferences(spKey, Context.MODE_PRIVATE);
+        SharedPreferences sp = Utilities.getPrefs(this);
         boolean show = sp.getBoolean(TestingUtils.SHOW_WEIGHT_WATCHER, true);
 
         show = !show;
diff --git a/src/com/android/launcher3/util/FocusLogic.java b/src/com/android/launcher3/util/FocusLogic.java
index 1c6efbc..2aae3c0 100644
--- a/src/com/android/launcher3/util/FocusLogic.java
+++ b/src/com/android/launcher3/util/FocusLogic.java
@@ -48,7 +48,7 @@
     private static final String TAG = "FocusLogic";
     private static final boolean DEBUG = false;
 
-    // Item and page index related constant used by {@link #handleKeyEvent}.
+    /** Item and page index related constant used by {@link #handleKeyEvent}. */
     public static final int NOOP = -1;
 
     public static final int PREVIOUS_PAGE_RIGHT_COLUMN  = -2;
@@ -91,7 +91,7 @@
         switch (keyCode) {
             case KeyEvent.KEYCODE_DPAD_LEFT:
                 newIndex = handleDpadHorizontal(iconIdx, cntX, cntY, map, -1 /*increment*/);
-                if (isRtl && newIndex == NOOP && pageIndex > 0) {
+                if (!isRtl && newIndex == NOOP && pageIndex > 0) {
                     newIndex = PREVIOUS_PAGE_RIGHT_COLUMN;
                 } else if (isRtl && newIndex == NOOP && pageIndex < pageCount - 1) {
                     newIndex = NEXT_PAGE_RIGHT_COLUMN;
@@ -99,7 +99,7 @@
                 break;
             case KeyEvent.KEYCODE_DPAD_RIGHT:
                 newIndex = handleDpadHorizontal(iconIdx, cntX, cntY, map, 1 /*increment*/);
-                if (isRtl && newIndex == NOOP && pageIndex < pageCount - 1) {
+                if (!isRtl && newIndex == NOOP && pageIndex < pageCount - 1) {
                     newIndex = NEXT_PAGE_LEFT_COLUMN;
                 } else if (isRtl && newIndex == NOOP && pageIndex > 0) {
                     newIndex = PREVIOUS_PAGE_LEFT_COLUMN;
@@ -165,8 +165,12 @@
 
         // Iterate thru the children.
         for (int i = 0; i < parent.getChildCount(); i++ ) {
-            int cx = ((CellLayout.LayoutParams) parent.getChildAt(i).getLayoutParams()).cellX;
-            int cy = ((CellLayout.LayoutParams) parent.getChildAt(i).getLayoutParams()).cellY;
+            View cell = parent.getChildAt(i);
+            if (!cell.isFocusable()) {
+                continue;
+            }
+            int cx = ((CellLayout.LayoutParams) cell.getLayoutParams()).cellX;
+            int cy = ((CellLayout.LayoutParams) cell.getLayoutParams()).cellY;
             matrix[invert ? (m - cx - 1) : cx][cy] = i;
         }
         if (DEBUG) {
@@ -199,8 +203,12 @@
 
         // Iterate thru the children of the top parent.
         for (int i = 0; i < iconParent.getChildCount(); i++) {
-            int cx = ((CellLayout.LayoutParams) iconParent.getChildAt(i).getLayoutParams()).cellX;
-            int cy = ((CellLayout.LayoutParams) iconParent.getChildAt(i).getLayoutParams()).cellY;
+            View cell = iconParent.getChildAt(i);
+            if (!cell.isFocusable()) {
+                continue;
+            }
+            int cx = ((CellLayout.LayoutParams) cell.getLayoutParams()).cellX;
+            int cy = ((CellLayout.LayoutParams) cell.getLayoutParams()).cellY;
             matrix[cx][cy] = i;
         }
 
@@ -253,8 +261,12 @@
 
         // Iterate thru the children of the top parent.
         for (int i = 0; i < iconParent.getChildCount(); i++) {
-            int cx = ((CellLayout.LayoutParams) iconParent.getChildAt(i).getLayoutParams()).cellX;
-            int cy = ((CellLayout.LayoutParams) iconParent.getChildAt(i).getLayoutParams()).cellY;
+            View cell = iconParent.getChildAt(i);
+            if (!cell.isFocusable()) {
+                continue;
+            }
+            int cx = ((CellLayout.LayoutParams) cell.getLayoutParams()).cellX;
+            int cy = ((CellLayout.LayoutParams) cell.getLayoutParams()).cellY;
             if (pivotX < 0) {
                 matrix[cx - pivotX][cy] = i;
             } else {
@@ -334,6 +346,18 @@
                 }
             }
         }
+
+        // Rule 3: if switching between pages, do a brute-force search to find an item that was
+        //         missed by rules 1 and 2 (such as when going from a bottom right icon to top left)
+        if (iconIdx == PIVOT) {
+            for (int x = xPos + increment; 0 <= x && x < cntX; x = x + increment) {
+                for (int y = 0; y < cntY; y++) {
+                    if ((newIconIndex = inspectMatrix(x, y, cntX, cntY, matrix)) != NOOP) {
+                        return newIconIndex;
+                    }
+                }
+            }
+        }
         return newIconIndex;
     }
 
@@ -482,9 +506,9 @@
     /**
      * @param edgeColumn the column of the new icon. either {@link #NEXT_PAGE_LEFT_COLUMN} or
      * {@link #NEXT_PAGE_RIGHT_COLUMN}
-     * @return the view adjacent to {@param oldView} in the {@param nextPage}.
+     * @return the view adjacent to {@param oldView} in the {@param nextPage} of the folder.
      */
-    public static View getAdjacentChildInNextPage(
+    public static View getAdjacentChildInNextFolderPage(
             ShortcutAndWidgetContainer nextPage, View oldView, int edgeColumn) {
         final int newRow = ((CellLayout.LayoutParams) oldView.getLayoutParams()).cellY;
 
diff --git a/src/com/android/launcher3/util/TestingUtils.java b/src/com/android/launcher3/util/TestingUtils.java
index 39b8046..665c371 100644
--- a/src/com/android/launcher3/util/TestingUtils.java
+++ b/src/com/android/launcher3/util/TestingUtils.java
@@ -13,6 +13,7 @@
 import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherAppState;
 import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
 
 import java.util.HashMap;
 
@@ -39,9 +40,7 @@
 
     public static void addWeightWatcher(Launcher launcher) {
         if (MEMORY_DUMP_ENABLED) {
-            String spKey = LauncherAppState.getSharedPreferencesKey();
-            SharedPreferences sp = launcher.getSharedPreferences(spKey, Context.MODE_PRIVATE);
-            boolean show = sp.getBoolean(SHOW_WEIGHT_WATCHER, true);
+            boolean show = Utilities.getPrefs(launcher).getBoolean(SHOW_WEIGHT_WATCHER, true);
 
             int id = launcher.getResources().getIdentifier("zzz_weight_watcher", "layout",
                     launcher.getPackageName());
diff --git a/src/com/android/launcher3/util/WallpaperOffsetInterpolator.java b/src/com/android/launcher3/util/WallpaperOffsetInterpolator.java
new file mode 100644
index 0000000..1fbd0dc
--- /dev/null
+++ b/src/com/android/launcher3/util/WallpaperOffsetInterpolator.java
@@ -0,0 +1,225 @@
+package com.android.launcher3.util;
+
+import android.app.WallpaperManager;
+import android.os.IBinder;
+import android.util.Log;
+import android.view.Choreographer;
+import android.view.animation.DecelerateInterpolator;
+import android.view.animation.Interpolator;
+
+import com.android.launcher3.Utilities;
+import com.android.launcher3.Workspace;
+
+/**
+ * Utility class to handle wallpaper scrolling along with workspace.
+ */
+public class WallpaperOffsetInterpolator implements Choreographer.FrameCallback {
+    private static final String TAG = "WPOffsetInterpolator";
+    private static final int ANIMATION_DURATION = 250;
+
+    // Don't use all the wallpaper for parallax until you have at least this many pages
+    private static final int MIN_PARALLAX_PAGE_SPAN = 3;
+
+    private final Choreographer mChoreographer;
+    private final Interpolator mInterpolator;
+    private final WallpaperManager mWallpaperManager;
+    private final Workspace mWorkspace;
+    private final boolean mIsRtl;
+
+    private IBinder mWindowToken;
+    private boolean mWallpaperIsLiveWallpaper;
+    private float mLastSetWallpaperOffsetSteps = 0;
+
+    private float mFinalOffset = 0.0f;
+    private float mCurrentOffset = 0.5f; // to force an initial update
+    private boolean mWaitingForUpdate;
+
+    private boolean mAnimating;
+    private long mAnimationStartTime;
+    private float mAnimationStartOffset;
+    int mNumScreens;
+    int mNumPagesForWallpaperParallax;
+
+    public WallpaperOffsetInterpolator(Workspace workspace) {
+        mChoreographer = Choreographer.getInstance();
+        mInterpolator = new DecelerateInterpolator(1.5f);
+
+        mWorkspace = workspace;
+        mWallpaperManager = WallpaperManager.getInstance(workspace.getContext());
+        mIsRtl = Utilities.isRtl(workspace.getResources());
+    }
+
+    @Override
+    public void doFrame(long frameTimeNanos) {
+        updateOffset(false);
+    }
+
+    private void updateOffset(boolean force) {
+        if (mWaitingForUpdate || force) {
+            mWaitingForUpdate = false;
+            if (computeScrollOffset() && mWindowToken != null) {
+                try {
+                    mWallpaperManager.setWallpaperOffsets(mWindowToken, getCurrX(), 0.5f);
+                    setWallpaperOffsetSteps();
+                } catch (IllegalArgumentException e) {
+                    Log.e(TAG, "Error updating wallpaper offset: " + e);
+                }
+            }
+        }
+    }
+
+    public boolean computeScrollOffset() {
+        final float oldOffset = mCurrentOffset;
+        if (mAnimating) {
+            long durationSinceAnimation = System.currentTimeMillis() - mAnimationStartTime;
+            float t0 = durationSinceAnimation / (float) ANIMATION_DURATION;
+            float t1 = mInterpolator.getInterpolation(t0);
+            mCurrentOffset = mAnimationStartOffset +
+                    (mFinalOffset - mAnimationStartOffset) * t1;
+            mAnimating = durationSinceAnimation < ANIMATION_DURATION;
+        } else {
+            mCurrentOffset = mFinalOffset;
+        }
+
+        if (Math.abs(mCurrentOffset - mFinalOffset) > 0.0000001f) {
+            scheduleUpdate();
+        }
+        if (Math.abs(oldOffset - mCurrentOffset) > 0.0000001f) {
+            return true;
+        }
+        return false;
+    }
+
+    public float wallpaperOffsetForScroll(int scroll) {
+        // TODO: do different behavior if it's  a live wallpaper?
+        // Don't use up all the wallpaper parallax until you have at least
+        // MIN_PARALLAX_PAGE_SPAN pages
+        int numScrollingPages = getNumScreensExcludingEmptyAndCustom();
+        int parallaxPageSpan;
+        if (mWallpaperIsLiveWallpaper) {
+            parallaxPageSpan = numScrollingPages - 1;
+        } else {
+            parallaxPageSpan = Math.max(MIN_PARALLAX_PAGE_SPAN, numScrollingPages - 1);
+        }
+        mNumPagesForWallpaperParallax = parallaxPageSpan;
+
+        if (mWorkspace.getChildCount() <= 1) {
+            if (mIsRtl) {
+                return 1 - 1.0f/mNumPagesForWallpaperParallax;
+            }
+            return 0;
+        }
+
+        // Exclude the leftmost page
+        int emptyExtraPages = numEmptyScreensToIgnore();
+        int firstIndex = mWorkspace.numCustomPages();
+        // Exclude the last extra empty screen (if we have > MIN_PARALLAX_PAGE_SPAN pages)
+        int lastIndex = mWorkspace.getChildCount() - 1 - emptyExtraPages;
+        if (mIsRtl) {
+            int temp = firstIndex;
+            firstIndex = lastIndex;
+            lastIndex = temp;
+        }
+
+        int firstPageScrollX = mWorkspace.getScrollForPage(firstIndex);
+        int scrollRange = mWorkspace.getScrollForPage(lastIndex) - firstPageScrollX;
+        if (scrollRange == 0) {
+            return 0;
+        } else {
+            // Sometimes the left parameter of the pages is animated during a layout transition;
+            // this parameter offsets it to keep the wallpaper from animating as well
+            int adjustedScroll =
+                    scroll - firstPageScrollX - mWorkspace.getLayoutTransitionOffsetForPage(0);
+            float offset = Math.min(1, adjustedScroll / (float) scrollRange);
+            offset = Math.max(0, offset);
+
+            // On RTL devices, push the wallpaper offset to the right if we don't have enough
+            // pages (ie if numScrollingPages < MIN_PARALLAX_PAGE_SPAN)
+            if (!mWallpaperIsLiveWallpaper && numScrollingPages < MIN_PARALLAX_PAGE_SPAN
+                    && mIsRtl) {
+                return offset * (parallaxPageSpan - numScrollingPages + 1) / parallaxPageSpan;
+            }
+            return offset * (numScrollingPages - 1) / parallaxPageSpan;
+        }
+    }
+
+    private float wallpaperOffsetForCurrentScroll() {
+        return wallpaperOffsetForScroll(mWorkspace.getScrollX());
+    }
+
+    private int numEmptyScreensToIgnore() {
+        int numScrollingPages = mWorkspace.getChildCount() - mWorkspace.numCustomPages();
+        if (numScrollingPages >= MIN_PARALLAX_PAGE_SPAN && mWorkspace.hasExtraEmptyScreen()) {
+            return 1;
+        } else {
+            return 0;
+        }
+    }
+
+    private int getNumScreensExcludingEmptyAndCustom() {
+        return mWorkspace.getChildCount() - numEmptyScreensToIgnore() - mWorkspace.numCustomPages();
+    }
+
+    public void syncWithScroll() {
+        float offset = wallpaperOffsetForCurrentScroll();
+        setFinalX(offset);
+        updateOffset(true);
+    }
+
+    public float getCurrX() {
+        return mCurrentOffset;
+    }
+
+    public float getFinalX() {
+        return mFinalOffset;
+    }
+
+    private void animateToFinal() {
+        mAnimating = true;
+        mAnimationStartOffset = mCurrentOffset;
+        mAnimationStartTime = System.currentTimeMillis();
+    }
+
+    private void setWallpaperOffsetSteps() {
+        // Set wallpaper offset steps (1 / (number of screens - 1))
+        float xOffset = 1.0f / mNumPagesForWallpaperParallax;
+        if (xOffset != mLastSetWallpaperOffsetSteps) {
+            mWallpaperManager.setWallpaperOffsetSteps(xOffset, 1.0f);
+            mLastSetWallpaperOffsetSteps = xOffset;
+        }
+    }
+
+    public void setFinalX(float x) {
+        scheduleUpdate();
+        mFinalOffset = Math.max(0f, Math.min(x, 1.0f));
+        if (getNumScreensExcludingEmptyAndCustom() != mNumScreens) {
+            if (mNumScreens > 0) {
+                // Don't animate if we're going from 0 screens
+                animateToFinal();
+            }
+            mNumScreens = getNumScreensExcludingEmptyAndCustom();
+        }
+    }
+
+    private void scheduleUpdate() {
+        if (!mWaitingForUpdate) {
+            mChoreographer.postFrameCallback(this);
+            mWaitingForUpdate = true;
+        }
+    }
+
+    public void jumpToFinal() {
+        mCurrentOffset = mFinalOffset;
+    }
+
+    public void onResume() {
+        mWallpaperIsLiveWallpaper = mWallpaperManager.getWallpaperInfo() != null;
+        // Force the wallpaper offset steps to be set again, because another app might have changed
+        // them
+        mLastSetWallpaperOffsetSteps = 0f;
+    }
+
+    public void setWindowToken(IBinder token) {
+        mWindowToken = token;
+    }
+}
\ No newline at end of file
diff --git a/src/com/android/launcher3/widget/WidgetHostViewLoader.java b/src/com/android/launcher3/widget/WidgetHostViewLoader.java
index 7607d85..b47ba84 100644
--- a/src/com/android/launcher3/widget/WidgetHostViewLoader.java
+++ b/src/com/android/launcher3/widget/WidgetHostViewLoader.java
@@ -4,9 +4,9 @@
 import android.appwidget.AppWidgetManager;
 import android.content.Context;
 import android.graphics.Rect;
-import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
+import android.util.Log;
 import android.view.View;
 
 import com.android.launcher3.AppWidgetResizeFrame;
@@ -16,11 +16,13 @@
 import com.android.launcher3.LauncherAppWidgetProviderInfo;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.compat.AppWidgetManagerCompat;
-import com.android.launcher3.dragndrop.DragController.DragListener;
+import com.android.launcher3.dragndrop.DragController;
 import com.android.launcher3.dragndrop.DragLayer;
 import com.android.launcher3.util.Thunk;
 
-public class WidgetHostViewLoader implements DragListener {
+public class WidgetHostViewLoader implements DragController.DragListener {
+    private static final String TAG = "WidgetHostViewLoader";
+    private static final boolean LOGD = false;
 
     /* Runnables to handle inflation and binding. */
     @Thunk Runnable mInflateWidgetRunnable = null;
@@ -49,6 +51,10 @@
 
     @Override
     public void onDragEnd() {
+        if (LOGD) {
+            Log.d(TAG, "Cleaning up in onDragEnd()...");
+        }
+
         // Cleanup up preloading state.
         mLauncher.getDragController().removeDragListener(this);
 
@@ -63,6 +69,9 @@
 
         // The widget was inflated and added to the DragLayer -- remove it.
         if (mInfo.boundWidget != null) {
+            if (LOGD) {
+                Log.d(TAG, "...removing widget from drag layer");
+            }
             mLauncher.getDragLayer().removeView(mInfo.boundWidget);
             mLauncher.getAppWidgetHost().deleteAppWidgetId(mInfo.boundWidget.getAppWidgetId());
             mInfo.boundWidget = null;
@@ -90,6 +99,9 @@
             @Override
             public void run() {
                 mWidgetLoadingId = mLauncher.getAppWidgetHost().allocateAppWidgetId();
+                if (LOGD) {
+                    Log.d(TAG, "Binding widget, id: " + mWidgetLoadingId);
+                }
                 if(AppWidgetManagerCompat.getInstance(mLauncher).bindAppWidgetIdIfAllowed(
                         mWidgetLoadingId, pInfo, options)) {
 
@@ -102,6 +114,9 @@
         mInflateWidgetRunnable = new Runnable() {
             @Override
             public void run() {
+                if (LOGD) {
+                    Log.d(TAG, "Inflating widget, id: " + mWidgetLoadingId);
+                }
                 if (mWidgetLoadingId == -1) {
                     return;
                 }
@@ -121,11 +136,17 @@
                 lp.x = lp.y = 0;
                 lp.customPosition = true;
                 hostView.setLayoutParams(lp);
+                if (LOGD) {
+                    Log.d(TAG, "Adding host view to drag layer");
+                }
                 mLauncher.getDragLayer().addView(hostView);
                 mView.setTag(mInfo);
             }
         };
 
+        if (LOGD) {
+            Log.d(TAG, "About to bind/inflate widget");
+        }
         mHandler.post(mBindWidgetRunnable);
         return true;
     }
diff --git a/src/com/android/launcher3/widget/WidgetsContainerView.java b/src/com/android/launcher3/widget/WidgetsContainerView.java
index 143f989..a1472cc 100644
--- a/src/com/android/launcher3/widget/WidgetsContainerView.java
+++ b/src/com/android/launcher3/widget/WidgetsContainerView.java
@@ -52,10 +52,9 @@
  * The widgets list view container.
  */
 public class WidgetsContainerView extends BaseContainerView
-        implements View.OnLongClickListener, View.OnClickListener, DragSource{
-
+        implements View.OnLongClickListener, View.OnClickListener, DragSource {
     private static final String TAG = "WidgetsContainerView";
-    private static final boolean DEBUG = false;
+    private static final boolean LOGD = false;
 
     /* Coefficient multiplied to the screen height for preloading widgets. */
     private static final int PRELOAD_SCREEN_HEIGHT_MULTIPLE = 1;
@@ -92,13 +91,14 @@
         mDragController = mLauncher.getDragController();
         mAdapter = new WidgetsListAdapter(this, this, mLauncher);
         mIconCache = (LauncherAppState.getInstance()).getIconCache();
-        if (DEBUG) {
+        if (LOGD) {
             Log.d(TAG, "WidgetsContainerView constructor");
         }
     }
 
     @Override
     protected void onFinishInflate() {
+        super.onFinishInflate();
         mContent = findViewById(R.id.content);
         mView = (WidgetsRecyclerView) findViewById(R.id.widgets_list_view);
         mView.setAdapter(mAdapter);
@@ -158,7 +158,7 @@
 
     @Override
     public boolean onLongClick(View v) {
-        if (DEBUG) {
+        if (LOGD) {
             Log.d(TAG, String.format("onLonglick [v=%s]", v));
         }
         // Return early if this is not initiated from a touch
@@ -173,7 +173,7 @@
         if (status && v.getTag() instanceof PendingAddWidgetInfo) {
             WidgetHostViewLoader hostLoader = new WidgetHostViewLoader(mLauncher, v);
             boolean preloadStatus = hostLoader.preloadWidget();
-            if (DEBUG) {
+            if (LOGD) {
                 Log.d(TAG, String.format("preloading widget [status=%s]", preloadStatus));
             }
             mLauncher.getDragController().addDragListener(hostLoader);
@@ -304,6 +304,9 @@
     @Override
     public void onDropCompleted(View target, DragObject d, boolean isFlingToDelete,
             boolean success) {
+        if (LOGD) {
+            Log.d(TAG, "onDropCompleted");
+        }
         if (isFlingToDelete || !success || (target != mLauncher.getWorkspace() &&
                 !(target instanceof DeleteDropTarget) && !(target instanceof Folder))) {
             // Exit spring loaded mode if we have not successfully dropped or have not handled the
diff --git a/tests/AndroidManifest.xml b/tests/AndroidManifest.xml
index 42ae5a3..8acc5e9 100644
--- a/tests/AndroidManifest.xml
+++ b/tests/AndroidManifest.xml
@@ -1,4 +1,4 @@
-<?xml version="2.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
 <!-- Copyright (C) 2015 The Android Open Source Project
 
     Licensed under the Apache License, Version 2.0 (the "License");
@@ -15,15 +15,17 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
     package="com.android.launcher3.tests">
 
+    <uses-sdk tools:overrideLibrary="android.support.test.uiautomator.v18"/>
+
     <application>
         <uses-library android:name="android.test.runner" />
     </application>
 
     <instrumentation
         android:name="android.test.InstrumentationTestRunner"
-        android:targetPackage="com.android.launcher3"
-        android:label="Unit tests for Launcher3">
+        android:targetPackage="com.android.launcher3" >
     </instrumentation>
 </manifest>
diff --git a/tests/src/com/android/launcher3/InvariantDeviceProfileTest.java b/tests/src/com/android/launcher3/InvariantDeviceProfileTest.java
index 1bc7c11..db3f72f 100644
--- a/tests/src/com/android/launcher3/InvariantDeviceProfileTest.java
+++ b/tests/src/com/android/launcher3/InvariantDeviceProfileTest.java
@@ -15,15 +15,14 @@
  */
 package com.android.launcher3;
 
+import android.content.res.Resources;
+import android.graphics.Point;
 import android.graphics.PointF;
+import android.graphics.Rect;
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.util.Log;
 
-import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.InvariantDeviceProfile;
-import com.android.launcher3.util.FocusLogic;
-
 import java.util.ArrayList;
 
 /**
@@ -52,9 +51,12 @@
 
     public void testFindClosestDeviceProfile2() {
         for (InvariantDeviceProfile idf: mPredefinedDeviceProfiles) {
+            ArrayList<InvariantDeviceProfile> predefinedProfilesCopy =
+                    new ArrayList<>(mPredefinedDeviceProfiles);
             ArrayList<InvariantDeviceProfile> closestProfiles =
                     mInvariantProfile.findClosestDeviceProfiles(
-                            idf.minWidthDps, idf.minHeightDps, mPredefinedDeviceProfiles);
+                            idf.minWidthDps, idf.minHeightDps, predefinedProfilesCopy
+                    );
             assertTrue(closestProfiles.get(0).equals(idf));
         }
     }
@@ -120,4 +122,72 @@
     // Add more tests for other devices, however, running them once on a single device is enough
     // for verifying that for a platform version, the WindowManager and DisplayMetrics is
     // working as intended.
+
+    /**
+     * Make sure that the height for the QSB is what we expect in normal mode.
+     */
+    public void testQsbNormalHeight() {
+        Resources resources = getContext().getResources();
+        DeviceProfile landscapeProfile = mInvariantProfile.landscapeProfile;
+        DeviceProfile portraitProfile = mInvariantProfile.portraitProfile;
+        landscapeProfile.setSearchBarHeight(LauncherCallbacks.SEARCH_BAR_HEIGHT_NORMAL);
+        portraitProfile.setSearchBarHeight(LauncherCallbacks.SEARCH_BAR_HEIGHT_NORMAL);
+        Rect portraitBounds = portraitProfile.getSearchBarBounds(true); // RTL shouldn't matter.
+        int portraitHeight = (int) Utilities.dpiFromPx(portraitBounds.height(),
+                resources.getDisplayMetrics());
+        Rect landscapeBounds = landscapeProfile.getSearchBarBounds(true); // RTL shouldn't matter.
+        int landscapeHeight = (int) Utilities.dpiFromPx(landscapeBounds.height(),
+                resources.getDisplayMetrics());
+        if (portraitProfile.isTablet) {
+            assertEquals(8 + 48 + 24, portraitHeight);
+        } else {
+            assertEquals(8 + 48 + 12, portraitHeight);
+        }
+        // Make sure the height that we pass in the widget options bundle is the height of the
+        // search bar + 8dps padding top and bottom.
+        Point portraitDimens = portraitProfile.getSearchBarDimensForWidgetOpts(resources);
+        int portraitWidgetOptsHeight = portraitDimens.y;
+        Point landscapeDimens = landscapeProfile.getSearchBarDimensForWidgetOpts(resources);
+        int landscapeWidgetOptsHeight = landscapeDimens.y;
+        assertEquals(8 + 48 + 8, (int) Utilities.dpiFromPx(portraitWidgetOptsHeight,
+                resources.getDisplayMetrics()));
+        if (!landscapeProfile.isVerticalBarLayout()) {
+            assertEquals(portraitHeight, landscapeHeight);
+            assertEquals(portraitWidgetOptsHeight, landscapeWidgetOptsHeight);
+        }
+    }
+
+    /**
+     * Make sure that the height for the QSB is what we expect in tall mode.
+     */
+    public void testQsbTallHeight() {
+        Resources resources = getContext().getResources();
+        DeviceProfile landscapeProfile = mInvariantProfile.landscapeProfile;
+        DeviceProfile portraitProfile = mInvariantProfile.portraitProfile;
+        landscapeProfile.setSearchBarHeight(LauncherCallbacks.SEARCH_BAR_HEIGHT_TALL);
+        portraitProfile.setSearchBarHeight(LauncherCallbacks.SEARCH_BAR_HEIGHT_TALL);
+        Rect portraitBounds = portraitProfile.getSearchBarBounds(true); // RTL shouldn't matter.
+        int portraitHeight = (int) Utilities.dpiFromPx(portraitBounds.height(),
+                resources.getDisplayMetrics());
+        Rect landscapeBounds = landscapeProfile.getSearchBarBounds(true); // RTL shouldn't matter.
+        int landscapeHeight = (int) Utilities.dpiFromPx(landscapeBounds.height(),
+                resources.getDisplayMetrics());
+        if (portraitProfile.isTablet) {
+            assertEquals(8 + 80 + 24, portraitHeight);
+        } else {
+            assertEquals(8 + 80 + 2, portraitHeight);
+        }
+        // Make sure the height that we pass in the widget options bundle is the height of the
+        // search bar + 8dps padding top and bottom.
+        Point portraitDimens = portraitProfile.getSearchBarDimensForWidgetOpts(resources);
+        int portraitWidgetOptsHeight = portraitDimens.y;
+        Point landscapeDimens = landscapeProfile.getSearchBarDimensForWidgetOpts(resources);
+        int landscapeWidgetOptsHeight = landscapeDimens.y;
+        assertEquals(8 + 80 + 8, (int) Utilities.dpiFromPx(portraitWidgetOptsHeight,
+                resources.getDisplayMetrics()));
+        if (!landscapeProfile.isVerticalBarLayout()) {
+            assertEquals(portraitHeight, landscapeHeight);
+            assertEquals(portraitWidgetOptsHeight, landscapeWidgetOptsHeight);
+        }
+    }
 }
diff --git a/tests/src/com/android/launcher3/RotationPreferenceTest.java b/tests/src/com/android/launcher3/RotationPreferenceTest.java
new file mode 100644
index 0000000..0168ee6
--- /dev/null
+++ b/tests/src/com/android/launcher3/RotationPreferenceTest.java
@@ -0,0 +1,88 @@
+package com.android.launcher3;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.graphics.Rect;
+import android.support.test.uiautomator.UiDevice;
+import android.support.test.uiautomator.UiObject;
+import android.support.test.uiautomator.UiSelector;
+import android.test.InstrumentationTestCase;
+
+/**
+ * Test for auto rotate preference.
+ */
+public class RotationPreferenceTest extends InstrumentationTestCase {
+
+    private UiDevice mDevice;
+    private Context mTargetContext;
+    private String mTargetPackage;
+
+    private SharedPreferences mPrefs;
+    private boolean mOriginalRotationValue;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        mDevice = UiDevice.getInstance(getInstrumentation());
+        mTargetContext = getInstrumentation().getTargetContext();
+        mTargetPackage = mTargetContext.getPackageName();
+        mPrefs = Utilities.getPrefs(mTargetContext);
+        mOriginalRotationValue = mPrefs.getBoolean(Utilities.ALLOW_ROTATION_PREFERENCE_KEY, false);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        setRotationEnabled(mOriginalRotationValue);
+        super.tearDown();
+    }
+
+    public void testRotation_disabled() throws Exception {
+        if (mTargetContext.getResources().getBoolean(R.bool.allow_rotation)) {
+            // This is a tablet. The test is only valid to mobile devices.
+            return;
+        }
+
+        setRotationEnabled(false);
+        mDevice.setOrientationRight();
+        goToLauncher();
+
+        Rect hotseat = getHotseatBounds();
+        assertTrue(hotseat.width() > hotseat.height());
+    }
+
+    public void testRotation_enabled() throws Exception {
+        if (mTargetContext.getResources().getBoolean(R.bool.allow_rotation)) {
+            // This is a tablet. The test is only valid to mobile devices.
+            return;
+        }
+
+        setRotationEnabled(true);
+        mDevice.setOrientationRight();
+        goToLauncher();
+
+        Rect hotseat = getHotseatBounds();
+        assertTrue(hotseat.width() < hotseat.height());
+    }
+
+    private void goToLauncher() {
+        Intent homeIntent = new Intent(Intent.ACTION_MAIN)
+                .addCategory(Intent.CATEGORY_HOME)
+                .setPackage(mTargetPackage)
+                .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        getInstrumentation().getContext().startActivity(homeIntent);
+        mDevice.findObject(new UiSelector().packageName(mTargetPackage)).waitForExists(6000);
+    }
+
+    private void setRotationEnabled(boolean enabled) {
+        mPrefs.edit().putBoolean(Utilities.ALLOW_ROTATION_PREFERENCE_KEY, enabled).commit();
+    }
+
+    private Rect getHotseatBounds() throws Exception {
+        UiObject hotseat = mDevice.findObject(
+                new UiSelector().resourceId(mTargetPackage + ":id/hotseat"));
+        hotseat.waitForExists(6000);
+        return hotseat.getVisibleBounds();
+    }
+}
diff --git a/tests/src/com/android/launcher3/util/FocusLogicTest.java b/tests/src/com/android/launcher3/util/FocusLogicTest.java
index ea87014..2c2f0d3 100644
--- a/tests/src/com/android/launcher3/util/FocusLogicTest.java
+++ b/tests/src/com/android/launcher3/util/FocusLogicTest.java
@@ -57,4 +57,39 @@
          // may get created in real world to test this method. OR 2) Move all the matrix
          // management routine to celllayout and write tests for them.
     }
+
+    public void testMoveFromBottomRightToBottomLeft() {
+        int[][] map = transpose(new int[][] {
+                {-1, 0, -1, -1, -1, -1},
+                {-1, -1, -1, -1, -1, -1},
+                {-1, -1, -1, -1, -1, -1},
+                {-1, -1, -1, -1, -1, -1},
+                {100, 1, -1, -1, -1, -1},
+        });
+        int i = FocusLogic.handleKeyEvent(KeyEvent.KEYCODE_DPAD_RIGHT, 6, 5, map, 100, 1, 2, false);
+        assertEquals(1, i);
+    }
+
+    public void testMoveFromBottomRightToTopLeft() {
+        int[][] map = transpose(new int[][] {
+                {-1, 0, -1, -1, -1, -1},
+                {-1, -1, -1, -1, -1, -1},
+                {-1, -1, -1, -1, -1, -1},
+                {-1, -1, -1, -1, -1, -1},
+                {100, -1, -1, -1, -1, -1},
+        });
+        int i = FocusLogic.handleKeyEvent(KeyEvent.KEYCODE_DPAD_RIGHT, 6, 5, map, 100, 1, 2, false);
+        assertEquals(0, i);
+    }
+
+    /** Transposes the matrix so that we can write it in human-readable format in the tests. */
+    private int[][] transpose(int[][] m) {
+        int[][] t = new int[m[0].length][m.length];
+        for (int i = 0; i < m.length; i++) {
+            for (int j = 0; j < m[0].length; j++) {
+                t[j][i] = m[i][j];
+            }
+        }
+        return t;
+    }
 }