[ThemePicker] Add bottom navbar to main activity

Set up the basic layout and add a bottom nav bar to
CustomizationPickerActivity, with basic support for
switching between section fragments.
(Fragments to be added in a separate CL)

Bug: 120560581
Change-Id: I06832260d20ca2938b6c04e110fadf45bc3070a2
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 7610e13..da3d15e 100755
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -8,14 +8,14 @@
         android:hardwareAccelerated="true"
         android:icon="@mipmap/product_logo_wallpapers_launcher_color_48"
         android:label="@string/app_name"
-        android:theme="@style/WallpaperTheme"
+        android:theme="@style/CustomizationTheme"
         android:requiredForAllUsers="true"
         android:restoreAnyVersion="true"
         android:supportsRtl="true">
 
         <activity android:name="com.android.theme.picker.ThemePickerActivity"
             android:label="@string/app_name"
-            android:theme="@style/WallpaperTheme"
+            android:theme="@style/CustomizationTheme.NoActionBar"
             android:resizeableActivity="true">
             <intent-filter>
                 <action android:name="android.intent.action.SET_WALLPAPER"/>
diff --git a/res/color/bottom_nav_item_color.xml b/res/color/bottom_nav_item_color.xml
new file mode 100644
index 0000000..d1c118b
--- /dev/null
+++ b/res/color/bottom_nav_item_color.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2018 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item
+        android:state_checked="true"
+        android:color="@color/accent_color" />
+    <item
+        android:state_checked="false"
+        android:color="@color/material_grey500" />
+</selector>
\ No newline at end of file
diff --git a/res/drawable/ic_nav_theme.xml b/res/drawable/ic_nav_theme.xml
new file mode 100644
index 0000000..52e3961
--- /dev/null
+++ b/res/drawable/ic_nav_theme.xml
@@ -0,0 +1,13 @@
+<!-- TODO (santie): replace with correct asset once available -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M12,2C6.48,2 2,6.48 2,12c0,5.52 4.48,10 10,10s10,-4.48 10,-10C22,6.48 17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8c0,-4.41 3.59,-8 8,-8s8,3.59 8,8C20,16.41 16.41,20 12,20z"/>
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M6.5,17.5l7.51,-3.49L17.5,6.5L9.99,9.99L6.5,17.5zM12,10.9c0.61,0 1.1,0.49 1.1,1.1s-0.49,1.1 -1.1,1.1s-1.1,-0.49 -1.1,-1.1S11.39,10.9 12,10.9z"/>
+</vector>
diff --git a/res/layout/activity_customization_picker_main.xml b/res/layout/activity_customization_picker_main.xml
new file mode 100755
index 0000000..40fcabb
--- /dev/null
+++ b/res/layout/activity_customization_picker_main.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2018 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<androidx.coordinatorlayout.widget.CoordinatorLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical">
+
+    <FrameLayout
+        android:id="@+id/fragment_container"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent" />
+
+    <com.google.android.material.bottomnavigation.BottomNavigationView
+        style="@style/BottomNavStyle"
+        android:id="@+id/main_bottom_nav"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_gravity="bottom"
+        app:labelVisibilityMode="labeled"
+        app:menu="@menu/bottom_navigation_menu"/>
+</androidx.coordinatorlayout.widget.CoordinatorLayout>
diff --git a/res/menu/bottom_navigation_menu.xml b/res/menu/bottom_navigation_menu.xml
new file mode 100644
index 0000000..4954206
--- /dev/null
+++ b/res/menu/bottom_navigation_menu.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2018 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+    <!-- TODO (santie): replace icons with real ones when available -->
+    <item
+        android:id="@+id/nav_theme"
+        android:title="@string/theme_title"
+        android:icon="@drawable/ic_nav_theme" />
+    <item
+        android:id="@+id/nav_clock"
+        android:title="@string/clock_title"
+        android:icon="@drawable/ic_nav_theme" />
+    <item
+        android:id="@+id/nav_grid"
+        android:title="@string/grid_title"
+        android:icon="@drawable/ic_nav_theme" />
+    <item
+        android:id="@+id/nav_wallpaper"
+        android:title="@string/wallpaper_title"
+        android:icon="@drawable/ic_nav_theme" />
+</menu>
\ No newline at end of file
diff --git a/res/values/colors.xml b/res/values/colors.xml
new file mode 100644
index 0000000..2bdd26a
--- /dev/null
+++ b/res/values/colors.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+     Copyright (C) 2018 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<resources>
+    <color name="status_bar_color">#ffffffff</color>
+
+    <color name="system_navigation_bar_background">@android:color/white</color>
+    <color name="system_navigation_bar_divider">#1f000000</color>
+</resources>
\ No newline at end of file
diff --git a/res/values/strings.xml b/res/values/strings.xml
index a57fd07..f04ee7e 100755
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -18,4 +18,19 @@
     <!-- The name of this application, a theme picker. [CHAR LIMIT=50] -->
     <string name="app_name">Themes &amp; Styles</string>
 
+    <!-- Title of a section of the customization picker where the user can select a Theme for the
+        device. [CHAR LIMIT=15] -->
+    <string name="theme_title">Theme</string>
+
+    <!-- Title of a section of the customization picker where the user can select a Clock face.
+        [CHAR LIMIT=15] -->
+    <string name="clock_title">Clock</string>
+
+    <!-- Title of a section of the customization picker where the user can select a Grid size for
+        the home screen. [CHAR LIMIT=15] -->
+    <string name="grid_title">Grid</string>
+
+    <!-- Title of a section of the customization picker where the user can select a Wallpaper.
+        [CHAR LIMIT=15] -->
+    <string name="wallpaper_title">Wallpaper</string>
 </resources>
diff --git a/res/values/styles.xml b/res/values/styles.xml
new file mode 100644
index 0000000..dcc76e5
--- /dev/null
+++ b/res/values/styles.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2018 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<resources>
+    <style name="CustomizationTheme" parent="@android:style/Theme.DeviceDefault.Settings">
+        <item name="colorPrimary">?android:colorPrimary</item>
+
+        <item name="android:statusBarColor">@android:color/white</item>
+        <item name="android:windowLightStatusBar">true</item>
+
+        <item name="android:navigationBarColor">@color/system_navigation_bar_background</item>
+        <item name="android:navigationBarDividerColor">@color/system_navigation_bar_divider</item>
+        <item name="android:windowLightNavigationBar">true</item>
+
+        <item name="selectableItemBackground">?android:attr/selectableItemBackground</item>
+    </style>
+    <style name="CustomizationTheme.NoActionBar">
+        <item name="android:windowActionBar">false</item>
+        <item name="android:windowNoTitle">true</item>
+    </style>
+    <style name="BottomNavStyle" parent="@style/Widget.MaterialComponents.BottomNavigationView">
+        <item name="itemIconTint">@color/bottom_nav_item_color</item>
+        <item name="itemTextColor">@color/bottom_nav_item_color</item>
+        <item name="itemTextAppearanceActive">@style/BottomNavTextAppearance</item>
+        <item name="itemTextAppearanceInactive">@style/BottomNavTextAppearance</item>
+    </style>
+
+    <style name="BottomNavTextAppearance" parent="@android:style/TextAppearance.Small">
+        <item name="android:textStyle">bold</item>
+    </style>
+</resources>
\ No newline at end of file
diff --git a/src/com/android/customization/picker/CustomizationPickerActivity.java b/src/com/android/customization/picker/CustomizationPickerActivity.java
index c482826..2eb0c93 100644
--- a/src/com/android/customization/picker/CustomizationPickerActivity.java
+++ b/src/com/android/customization/picker/CustomizationPickerActivity.java
@@ -18,15 +18,23 @@
 import android.content.Intent;
 import android.os.Bundle;
 import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
 
+import androidx.annotation.IdRes;
 import androidx.annotation.Nullable;
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentActivity;
+import androidx.fragment.app.FragmentManager;
+import androidx.fragment.app.FragmentTransaction;
 
+import com.android.wallpaper.R;
 import com.android.wallpaper.model.WallpaperInfo;
+import com.android.wallpaper.module.DailyLoggingAlarmScheduler;
 import com.android.wallpaper.module.FormFactorChecker;
 import com.android.wallpaper.module.Injector;
 import com.android.wallpaper.module.InjectorProvider;
 import com.android.wallpaper.module.UserEventLogger;
-import com.android.wallpaper.picker.BaseActivity;
 import com.android.wallpaper.picker.CategoryFragment;
 import com.android.wallpaper.picker.CategoryFragment.CategoryFragmentHost;
 import com.android.wallpaper.picker.MyPhotosLauncher.PermissionChangedListener;
@@ -34,14 +42,26 @@
 import com.android.wallpaper.picker.WallpaperPickerDelegate;
 import com.android.wallpaper.picker.WallpapersUiContainer;
 
-//TODO(santie): implement
-public class CustomizationPickerActivity extends BaseActivity implements WallpapersUiContainer,
+import com.google.android.material.bottomnavigation.BottomNavigationView;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ *  Main Activity allowing containing a bottom nav bar for the user to switch between the different
+ *  Fragments providing customization options.
+ */
+public class CustomizationPickerActivity extends FragmentActivity implements WallpapersUiContainer,
         CategoryFragmentHost {
 
     private static final String TAG = "CustomizationPickerActivity";
 
     private WallpaperPickerDelegate mDelegate;
     private UserEventLogger mUserEventLogger;
+    private BottomNavigationView mBottomNav;
+
+    private static final Map<Integer, CustomizationSection> mSections = new HashMap<>();
+    private CategoryFragment mWallpaperCategoryFragment;
 
     @Override
     protected void onCreate(@Nullable Bundle savedInstanceState) {
@@ -50,19 +70,77 @@
         mDelegate = new WallpaperPickerDelegate(this, this, injector);
         mUserEventLogger = injector.getUserEventLogger(this);
 
+        initSections();
+
         if (!supportsCustomization()) {
             Log.w(TAG, "Themes not supported, reverting to Wallpaper Picker");
             Intent intent = new Intent(this, TopLevelPickerActivity.class);
             startActivity(intent);
             finish();
         }
+
+        setContentView(R.layout.activity_customization_picker_main);
+        setUpBottomNavView();
+
+        FragmentManager fm = getSupportFragmentManager();
+        Fragment fragment = fm.findFragmentById(R.id.fragment_container);
+
+        boolean forceCategoryRefresh = false;
+        if (fragment == null) {
+            // App launch specific logic: log the "app launched" event and set up daily logging.
+            mUserEventLogger.logAppLaunched();
+            DailyLoggingAlarmScheduler.setAlarm(getApplicationContext());
+            navigateToSection(R.id.nav_wallpaper);
+            forceCategoryRefresh = true;
+        }
+
+        mDelegate.initialize(forceCategoryRefresh);
+
     }
 
     private boolean supportsCustomization() {
-        // TODO (santie): check for actual themes support
-        return mDelegate.getFormFactor() == FormFactorChecker.FORM_FACTOR_MOBILE;
+        //TODO (santie): the check for sections.size() should be > 1: if we only have wallpaper we
+        // should default to the Wallpaper only UI
+        return mDelegate.getFormFactor() == FormFactorChecker.FORM_FACTOR_MOBILE
+                && mSections.size() > 0;
     }
 
+    private void initSections() {
+        mSections.put(R.id.nav_wallpaper, new WallpaperSection(R.id.nav_wallpaper));
+        //TODO (santie): add other sections if supported by the device
+    }
+
+    private void setUpBottomNavView() {
+        mBottomNav = findViewById(R.id.main_bottom_nav);
+        Menu menu = mBottomNav.getMenu();
+        for (int i = menu.size() - 1; i >= 0; i--) {
+            MenuItem item = menu.getItem(i);
+            if (!mSections.containsKey(item.getItemId())) {
+                menu.removeItem(item.getItemId());
+            }
+        }
+
+        mBottomNav.setOnNavigationItemSelectedListener(item -> {
+            switchFragment(item.getItemId());
+            return true;
+        });
+    }
+
+    private void navigateToSection(@IdRes int id) {
+        mBottomNav.setSelectedItemId(id);
+    }
+
+    private void switchFragment(int id) {
+        final FragmentManager fragmentManager = getSupportFragmentManager();
+
+        Fragment fragment = mSections.get(id).getFragment();
+
+        final FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
+        fragmentTransaction.replace(R.id.fragment_container, fragment);
+        fragmentTransaction.commitNow();
+    }
+
+
     @Override
     public void requestExternalStoragePermission(PermissionChangedListener listener) {
 
@@ -94,11 +172,52 @@
     @Nullable
     @Override
     public CategoryFragment getCategoryFragment() {
-        return null;
+        return mWallpaperCategoryFragment;
     }
 
     @Override
     public void doneFetchingCategories() {
 
     }
+
+    /**
+     * Represents a section of the Picker (eg "Theme", "Clock", etc).
+     * There should be a concrete subclass per available section, providing the corresponding
+     * Fragment to be displayed when switching to each section.
+     */
+    static abstract class CustomizationSection {
+
+        /**
+         * IdRes used to identify this section in the BottomNavigationView menu.
+         */
+        @IdRes final int id;
+
+        private CustomizationSection(@IdRes int id) {
+            this.id = id;
+        }
+
+        /**
+         * @return the Fragment corresponding to this section.
+         */
+        abstract Fragment getFragment();
+
+    }
+
+    /**
+     * {@link CustomizationSection} corresponding to the "Wallpaper" section of the Picker.
+     */
+    private class WallpaperSection extends CustomizationSection {
+
+        private WallpaperSection(int id) {
+            super(id);
+        }
+
+        @Override
+        Fragment getFragment() {
+            if (mWallpaperCategoryFragment == null) {
+                mWallpaperCategoryFragment = new CategoryFragment();
+            }
+            return mWallpaperCategoryFragment;
+        }
+    }
 }