Merge "Import translations. DO NOT MERGE" into ub-launcher3-master
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 8f0f056..47edadd 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -184,4 +184,9 @@
 
 <!-- Touch handling -->
     <dimen name="edge_of_screen_threshold">8dp</dimen>
+
+<!-- Other -->
+    <!-- Approximates the system status bar height. Not guaranteed to be always be correct. -->
+    <dimen name="status_bar_height">24dp</dimen>
+
 </resources>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 87a5629..cd06b75 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -101,8 +101,8 @@
     <!-- Drop targets -->
     <style name="DropTargetButtonBase">
         <item name="android:drawablePadding">7.5dp</item>
-        <item name="android:paddingLeft">25dp</item>
-        <item name="android:paddingRight">25dp</item>
+        <item name="android:paddingLeft">16dp</item>
+        <item name="android:paddingRight">16dp</item>
         <item name="android:textColor">#FFFFFFFF</item>
         <item name="android:textSize">@dimen/drop_target_text_size</item>
         <item name="android:singleLine">true</item>
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index b18dee3..0a14c42 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -254,7 +254,6 @@
     @Thunk WidgetsContainerView mWidgetsView;
     @Thunk WidgetsModel mWidgetsModel;
 
-    private Bundle mSavedState;
     // We set the state in both onCreate and then onNewIntent in some cases, which causes both
     // scroll issues (because the workspace may not have been measured yet) and extra work.
     // Instead, just save the state that we need to restore Launcher to, and commit it in onResume.
@@ -277,9 +276,9 @@
     private LauncherAccessibilityDelegate mAccessibilityDelegate;
     private boolean mIsResumeFromActionScreenOff;
     @Thunk boolean mUserPresent = true;
-    private boolean mVisible = false;
-    private boolean mHasFocus = false;
-    private boolean mAttached = false;
+    private boolean mVisible;
+    private boolean mHasFocus;
+    private boolean mAttached;
 
     /** Maps launcher activity components to their list of shortcut ids. */
     private MultiHashMap<ComponentKey, String> mDeepShortcutMap = new MultiHashMap<>();
@@ -440,8 +439,7 @@
 
         lockAllApps();
 
-        mSavedState = savedInstanceState;
-        restoreState(mSavedState);
+        restoreState(savedInstanceState);
 
         if (LauncherAppState.PROFILE_STARTUP) {
             Trace.endSection();
@@ -449,11 +447,18 @@
 
         // We only load the page synchronously if the user rotates (or triggers a
         // configuration change) while launcher is in the foreground
-        if (!mModel.startLoader(mWorkspace.getRestorePage())) {
+        int currentScreen = PagedView.INVALID_RESTORE_PAGE;
+        if (savedInstanceState != null) {
+            currentScreen = savedInstanceState.getInt(RUNTIME_STATE_CURRENT_SCREEN, currentScreen);
+        }
+        if (!mModel.startLoader(currentScreen)) {
             // If we are not binding synchronously, show a fade in animation when
             // the first page bind completes.
             mDragLayer.setAlpha(0);
         } else {
+            // Pages bound synchronously.
+            mWorkspace.setCurrentPage(currentScreen);
+
             setWorkspaceLoading(true);
         }
 
@@ -490,10 +495,33 @@
 
     private void loadExtractedColorsAndColorItems() {
         // TODO: do this in pre-N as well, once the extraction part is complete.
-        if (mExtractedColors != null && Utilities.isNycOrAbove()) {
+        if (Utilities.isNycOrAbove()) {
             mExtractedColors.load(this);
             mHotseat.updateColor(mExtractedColors, !mPaused);
             mWorkspace.getPageIndicator().updateColor(mExtractedColors);
+            // It's possible that All Apps is visible when this is run,
+            // so always use light status bar in that case.
+            activateLightStatusBar(isAllAppsVisible());
+        }
+    }
+
+    /**
+     * Sets the status bar to be light or not. Light status bar means dark icons.
+     * @param activate if true, make sure the status bar is light, otherwise base on wallpaper.
+     */
+    public void activateLightStatusBar(boolean activate) {
+        boolean lightStatusBar = activate
+                || mExtractedColors.getColor(ExtractedColors.STATUS_BAR_INDEX,
+                ExtractedColors.DEFAULT_DARK) == ExtractedColors.DEFAULT_LIGHT;
+        int oldSystemUiFlags = getWindow().getDecorView().getSystemUiVisibility();
+        int newSystemUiFlags = oldSystemUiFlags;
+        if (lightStatusBar) {
+            newSystemUiFlags |= View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
+        } else {
+            newSystemUiFlags &= ~(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
+        }
+        if (newSystemUiFlags != oldSystemUiFlags) {
+            getWindow().getDecorView().setSystemUiVisibility(newSystemUiFlags);
         }
     }
 
@@ -594,7 +622,7 @@
     }
 
     /**
-     * Invoked by subclasses to signal a change to the {@link #addCustomContentToLeft} value to
+     * Invoked by subclasses to signal a change to the {@link #addToCustomContentPage} value to
      * ensure the custom content page is added or removed if necessary.
      */
     protected void invalidateHasCustomContentToLeft() {
@@ -1246,22 +1274,6 @@
     }
 
     /**
-     * Given the integer (ordinal) value of a State enum instance, convert it to a variable of type
-     * State
-     */
-    private static State intToState(int stateOrdinal) {
-        State state = State.WORKSPACE;
-        final State[] stateValues = State.values();
-        for (int i = 0; i < stateValues.length; i++) {
-            if (stateValues[i].ordinal() == stateOrdinal) {
-                state = stateValues[i];
-                break;
-            }
-        }
-        return state;
-    }
-
-    /**
      * Restores the previous state, if it exists.
      *
      * @param savedState The previous state.
@@ -1271,17 +1283,14 @@
             return;
         }
 
-        State state = intToState(savedState.getInt(RUNTIME_STATE, State.WORKSPACE.ordinal()));
+        int stateOrdinal = savedState.getInt(RUNTIME_STATE, State.WORKSPACE.ordinal());
+        State[] stateValues = State.values();
+        State state = (stateOrdinal >= 0 && stateOrdinal < stateValues.length)
+                ? stateValues[stateOrdinal] : State.WORKSPACE;
         if (state == State.APPS || state == State.WIDGETS) {
             mOnResumeState = state;
         }
 
-        int currentScreen = savedState.getInt(RUNTIME_STATE_CURRENT_SCREEN,
-                PagedView.INVALID_RESTORE_PAGE);
-        if (currentScreen != PagedView.INVALID_RESTORE_PAGE) {
-            mWorkspace.setRestorePage(currentScreen);
-        }
-
         PendingRequestArgs requestArgs = savedState.getParcelable(RUNTIME_STATE_PENDING_REQUEST_ARGS);
         if (requestArgs != null) {
             setWaitingForResult(requestArgs);
@@ -1799,11 +1808,14 @@
         }
         super.onNewIntent(intent);
 
-        // Close the menu
-        Folder openFolder = mWorkspace.getOpenFolder();
         boolean alreadyOnHome = mHasFocus && ((intent.getFlags() &
                 Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT)
                 != Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
+
+        // Check this condition before handling isActionMain, as this will get reset.
+        boolean shouldMoveToDefaultScreen = alreadyOnHome &&
+                mState == State.WORKSPACE && getTopFloatingView() == null;
+
         boolean isActionMain = Intent.ACTION_MAIN.equals(intent.getAction());
         if (isActionMain) {
             // also will cancel mWaitingForResult.
@@ -1858,10 +1870,10 @@
         // as slow logic in the callbacks eat into the time the scroller expects for the snapToPage
         // animation.
         if (isActionMain) {
-            boolean moveToDefaultScreen = mLauncherCallbacks != null ?
+            boolean callbackAllowsMoveToDefaultScreen = mLauncherCallbacks != null ?
                     mLauncherCallbacks.shouldMoveToDefaultScreenOnHomeIntent() : true;
-            if (alreadyOnHome && mState == State.WORKSPACE && !mWorkspace.isTouchActive() &&
-                    openFolder == null && moveToDefaultScreen) {
+            if (shouldMoveToDefaultScreen && !mWorkspace.isTouchActive()
+                    && callbackAllowsMoveToDefaultScreen) {
 
                 // We use this flag to suppress noisy callbacks above custom content state
                 // from onResume.
@@ -2761,6 +2773,7 @@
         }
     }
 
+    @TargetApi(Build.VERSION_CODES.M)
     private Bundle getActivityLaunchOptions(View v) {
         if (Utilities.ATLEAST_MARSHMALLOW) {
             int left = 0, top = 0;
@@ -3976,14 +3989,6 @@
         if (LauncherAppState.PROFILE_STARTUP) {
             Trace.beginSection("Page bind completed");
         }
-        if (mSavedState != null) {
-            if (!mWorkspace.hasFocus()) {
-                mWorkspace.getChildAt(mWorkspace.getCurrentPage()).requestFocus();
-            }
-
-            mSavedState = null;
-        }
-
         mWorkspace.restoreInstanceStateForRemainingPages();
 
         setWorkspaceLoading(false);
@@ -4405,7 +4410,6 @@
      */
     public void dumpState() {
         Log.d(TAG, "BEGIN launcher3 dump state for launcher " + this);
-        Log.d(TAG, "mSavedState=" + mSavedState);
         Log.d(TAG, "mWorkspaceLoading=" + mWorkspaceLoading);
         Log.d(TAG, "mPendingRequestArgs=" + mPendingRequestArgs);
         Log.d(TAG, "mPendingActivityResult=" + mPendingActivityResult);
diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java
index bea55d2..0b9bf09 100644
--- a/src/com/android/launcher3/PagedView.java
+++ b/src/com/android/launcher3/PagedView.java
@@ -98,7 +98,6 @@
 
     @ViewDebug.ExportedProperty(category = "launcher")
     protected int mCurrentPage;
-    protected int mRestorePage = INVALID_RESTORE_PAGE;
     private int mChildCountOnLastLayout;
 
     @ViewDebug.ExportedProperty(category = "launcher")
@@ -418,17 +417,6 @@
     }
 
     /**
-     * The restore page will be set in place of the current page at the next (likely first)
-     * layout.
-     */
-    void setRestorePage(int restorePage) {
-        mRestorePage = restorePage;
-    }
-    int getRestorePage() {
-        return mRestorePage;
-    }
-
-    /**
      * Should be called whenever the page changes. In the case of a scroll, we wait until the page
      * has settled.
      */
@@ -879,12 +867,7 @@
         }
 
         if (mScroller.isFinished() && mChildCountOnLastLayout != childCount) {
-            if (mRestorePage != INVALID_RESTORE_PAGE) {
-                setCurrentPage(mRestorePage);
-                mRestorePage = INVALID_RESTORE_PAGE;
-            } else {
-                setCurrentPage(getNextPage());
-            }
+            setCurrentPage(getNextPage());
         }
         mChildCountOnLastLayout = childCount;
 
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 977395f..af4dc07 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -734,11 +734,7 @@
         addFullScreenPage(customScreen);
 
         // Update the custom content hint
-        if (mRestorePage != INVALID_RESTORE_PAGE) {
-            mRestorePage = mRestorePage + 1;
-        } else {
-            setCurrentPage(getCurrentPage() + 1);
-        }
+        setCurrentPage(getCurrentPage() + 1);
     }
 
     public void removeCustomContentPage() {
@@ -759,11 +755,7 @@
         mCustomContentCallbacks = null;
 
         // Update the custom content hint
-        if (mRestorePage != INVALID_RESTORE_PAGE) {
-            mRestorePage = mRestorePage - 1;
-        } else {
-            setCurrentPage(getCurrentPage() - 1);
-        }
+        setCurrentPage(getCurrentPage() - 1);
     }
 
     public void addToCustomContentPage(View customContent, CustomContentCallbacks callbacks,
@@ -1753,7 +1745,7 @@
     }
 
     public boolean isOnOrMovingToCustomContent() {
-        return hasCustomContent() && getNextPage() == 0 && mRestorePage == INVALID_RESTORE_PAGE;
+        return hasCustomContent() && getNextPage() == 0;
     }
 
     private void updateStateForCustomContent(int screenCenter) {
diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
index 05ee577..892b88b 100644
--- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java
+++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
@@ -86,8 +86,6 @@
     private AnimatorSet mCurrentAnimation;
     private boolean mNoIntercept;
 
-    private boolean mLightStatusBar;
-
     // Used in discovery bounce animation to provide the transition without workspace changing.
     private boolean mIsTranslateWithoutWorkspace = false;
     private AnimatorSet mDiscoBounceAnimation;
@@ -273,26 +271,14 @@
     }
 
     private void updateLightStatusBar(float shift) {
-        boolean enable = shift <= mStatusBarHeight / 2;
         // Do not modify status bar on landscape as all apps is not full bleed.
         if (mLauncher.getDeviceProfile().isVerticalBarLayout()) {
             return;
         }
-        // Already set correctly
-        if (mLightStatusBar == enable) {
-            return;
-        }
-        int systemUiFlags = mLauncher.getWindow().getDecorView().getSystemUiVisibility();
-        if (enable) {
-            mLauncher.getWindow().getDecorView().setSystemUiVisibility(systemUiFlags
-                    | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
-
-        } else {
-            mLauncher.getWindow().getDecorView().setSystemUiVisibility(systemUiFlags
-                    & ~(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR));
-
-        }
-        mLightStatusBar = enable;
+        // Use a light status bar (dark icons) if all apps is behind at least half of the status
+        // bar. If the status bar is already light due to wallpaper extraction, keep it that way.
+        boolean forceLight = shift <= mStatusBarHeight / 2;
+        mLauncher.activateLightStatusBar(forceLight);
     }
 
     /**
diff --git a/src/com/android/launcher3/dynamicui/ColorExtractionService.java b/src/com/android/launcher3/dynamicui/ColorExtractionService.java
index 89594f4..c15b710 100644
--- a/src/com/android/launcher3/dynamicui/ColorExtractionService.java
+++ b/src/com/android/launcher3/dynamicui/ColorExtractionService.java
@@ -26,6 +26,7 @@
 
 import com.android.launcher3.LauncherProvider;
 import com.android.launcher3.LauncherSettings;
+import com.android.launcher3.R;
 
 /**
  * Extracts colors from the wallpaper, and saves results to {@link LauncherProvider}.
@@ -52,16 +53,21 @@
             Bitmap wallpaper = ((BitmapDrawable) wallpaperManager.getDrawable()).getBitmap();
             Palette palette = Palette.from(wallpaper).generate();
             extractedColors.updatePalette(palette);
-            // We extract colors for the hotseat separately,
-            // since it only considers the lower part of the wallpaper.
-            // TODO(twickham): update Palette library to 23.3.1 or higher,
-            // which fixes a bug with using regions (b/28349435).
+            // We extract colors for the hotseat and status bar separately,
+            // since they only consider part of the wallpaper.
             Palette hotseatPalette = Palette.from(wallpaper)
                     .setRegion(0, (int) (wallpaper.getHeight() * (1f - HOTSEAT_FRACTION)),
                             wallpaper.getWidth(), wallpaper.getHeight())
                     .clearFilters()
                     .generate();
             extractedColors.updateHotseatPalette(hotseatPalette);
+
+            int statusBarHeight = getResources().getDimensionPixelSize(R.dimen.status_bar_height);
+            Palette statusBarPalette = Palette.from(wallpaper)
+                    .setRegion(0, 0, wallpaper.getWidth(), statusBarHeight)
+                    .clearFilters()
+                    .generate();
+            extractedColors.updateStatusBarPalette(statusBarPalette);
         }
 
         // Save the extracted colors and wallpaper id to LauncherProvider.
diff --git a/src/com/android/launcher3/dynamicui/ExtractedColors.java b/src/com/android/launcher3/dynamicui/ExtractedColors.java
index e545288..4db0797 100644
--- a/src/com/android/launcher3/dynamicui/ExtractedColors.java
+++ b/src/com/android/launcher3/dynamicui/ExtractedColors.java
@@ -38,6 +38,7 @@
     // loading extracted colors. New colors should always be added at the end.
     public static final int VERSION_INDEX = 0;
     public static final int HOTSEAT_INDEX = 1;
+    public static final int STATUS_BAR_INDEX = 2;
     // public static final int VIBRANT_INDEX = 2;
     // public static final int VIBRANT_DARK_INDEX = 3;
     // public static final int VIBRANT_LIGHT_INDEX = 4;
@@ -45,8 +46,8 @@
     // public static final int MUTED_DARK_INDEX = 6;
     // public static final int MUTED_LIGHT_INDEX = 7;
 
-    public static final int NUM_COLOR_PROFILES = 1;
-    private static final int VERSION = 1;
+    public static final int NUM_COLOR_PROFILES = 2;
+    private static final int VERSION = 2;
 
     private static final String COLOR_SEPARATOR = ",";
 
@@ -156,4 +157,9 @@
         }
         setColorAtIndex(HOTSEAT_INDEX, hotseatColor);
     }
+
+    public void updateStatusBarPalette(Palette statusBarPalette) {
+        setColorAtIndex(STATUS_BAR_INDEX, ExtractionUtils.isSuperLight(statusBarPalette) ?
+                DEFAULT_LIGHT : DEFAULT_DARK);
+    }
 }