Add a secondary launcher activity (1/2)
This secondary launcher activity with new category SECONDARY_HOME and multiple instance supporrted could be used on sencondary display. Bug: 118206886 Bug: 114329798 Test: Manual Change-Id: Ibaecf8ef7614389760d0fcc547ef6d378a921583
This commit is contained in:
parent
4d64da3259
commit
3516bd89d9
|
@ -108,7 +108,9 @@ include $(CLEAR_VARS)
|
|||
LOCAL_USE_AAPT2 := true
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
|
||||
LOCAL_STATIC_ANDROID_LIBRARIES := Launcher3CommonDepsLib
|
||||
LOCAL_STATIC_ANDROID_LIBRARIES := \
|
||||
Launcher3CommonDepsLib \
|
||||
SecondaryDisplayLauncherLib
|
||||
LOCAL_SRC_FILES := \
|
||||
$(call all-java-files-under, src) \
|
||||
$(call all-java-files-under, src_shortcuts_overrides) \
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_USE_AAPT2 := true
|
||||
LOCAL_AAPT2_ONLY := true
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
|
||||
LOCAL_STATIC_ANDROID_LIBRARIES := androidx.design_design
|
||||
|
||||
LOCAL_STATIC_JAVA_LIBRARIES := LauncherPluginLib
|
||||
|
||||
LOCAL_SRC_FILES := $(call all-java-files-under, src)
|
||||
|
||||
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
|
||||
|
||||
LOCAL_PROGUARD_ENABLED := disabled
|
||||
|
||||
LOCAL_SDK_VERSION := current
|
||||
LOCAL_MIN_SDK_VERSION := 21
|
||||
LOCAL_MODULE := SecondaryDisplayLauncherLib
|
||||
LOCAL_PRIVILEGED_MODULE := true
|
||||
|
||||
include $(BUILD_STATIC_JAVA_LIBRARY)
|
|
@ -0,0 +1,40 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
/*
|
||||
**
|
||||
** Copyright 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.
|
||||
*/
|
||||
-->
|
||||
<manifest
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.android.launcher3">
|
||||
|
||||
<application>
|
||||
|
||||
<activity
|
||||
android:name="com.android.launcher3.SecondaryDisplayLauncher"
|
||||
android:theme="@style/SecondaryLauncherTheme"
|
||||
android:launchMode="singleTop"
|
||||
android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout|colorMode|density"
|
||||
android:enabled="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.SECONDARY_HOME" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
</application>
|
||||
</manifest>
|
|
@ -0,0 +1,22 @@
|
|||
<?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.
|
||||
-->
|
||||
|
||||
<vector android:height="24dp" android:tint="#FFFFFF"
|
||||
android:viewportHeight="24.0" android:viewportWidth="24.0"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="#FF000000" android:pathData="M4,8h4L8,4L4,4v4zM10,20h4v-4h-4v4zM4,20h4v-4L4,16v4zM4,14h4v-4L4,10v4zM10,14h4v-4h-4v4zM16,4v4h4L20,4h-4zM10,8h4L14,4h-4v4zM16,14h4v-4h-4v4zM16,20h4v-4h-4v4z"/>
|
||||
</vector>
|
|
@ -0,0 +1,22 @@
|
|||
<?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.
|
||||
-->
|
||||
|
||||
<vector android:height="24dp" android:tint="#FFFFFF"
|
||||
android:viewportHeight="24.0" android:viewportWidth="24.0"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="#FF000000" android:pathData="M19.43,12.98c0.04,-0.32 0.07,-0.64 0.07,-0.98s-0.03,-0.66 -0.07,-0.98l2.11,-1.65c0.19,-0.15 0.24,-0.42 0.12,-0.64l-2,-3.46c-0.12,-0.22 -0.39,-0.3 -0.61,-0.22l-2.49,1c-0.52,-0.4 -1.08,-0.73 -1.69,-0.98l-0.38,-2.65C14.46,2.18 14.25,2 14,2h-4c-0.25,0 -0.46,0.18 -0.49,0.42l-0.38,2.65c-0.61,0.25 -1.17,0.59 -1.69,0.98l-2.49,-1c-0.23,-0.09 -0.49,0 -0.61,0.22l-2,3.46c-0.13,0.22 -0.07,0.49 0.12,0.64l2.11,1.65c-0.04,0.32 -0.07,0.65 -0.07,0.98s0.03,0.66 0.07,0.98l-2.11,1.65c-0.19,0.15 -0.24,0.42 -0.12,0.64l2,3.46c0.12,0.22 0.39,0.3 0.61,0.22l2.49,-1c0.52,0.4 1.08,0.73 1.69,0.98l0.38,2.65c0.03,0.24 0.24,0.42 0.49,0.42h4c0.25,0 0.46,-0.18 0.49,-0.42l0.38,-2.65c0.61,-0.25 1.17,-0.59 1.69,-0.98l2.49,1c0.23,0.09 0.49,0 0.61,-0.22l2,-3.46c0.12,-0.22 0.07,-0.49 -0.12,-0.64l-2.11,-1.65zM12,15.5c-1.93,0 -3.5,-1.57 -3.5,-3.5s1.57,-3.5 3.5,-3.5 3.5,1.57 3.5,3.5 -1.57,3.5 -3.5,3.5z"/>
|
||||
</vector>
|
|
@ -0,0 +1,56 @@
|
|||
<?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"
|
||||
android:id="@+id/RootView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/launcher_bg_color"
|
||||
android:fitsSystemWindows="true" >
|
||||
|
||||
<GridView
|
||||
android:id="@+id/pinned_app_grid"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="@dimen/app_grid_margin_top"
|
||||
android:layout_marginStart="@dimen/app_grid_margin_left"
|
||||
android:layout_marginEnd="@dimen/app_grid_margin_right"
|
||||
android:columnWidth="@dimen/app_list_col_width"
|
||||
android:verticalSpacing="@dimen/app_list_horizontal_spacing"
|
||||
android:horizontalSpacing="@dimen/app_list_vertical_spacing"
|
||||
android:numColumns="auto_fit" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/OptionsButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom|start"
|
||||
android:layout_marginStart="@dimen/options_button_margin"
|
||||
android:layout_marginBottom="@dimen/options_button_margin"
|
||||
android:src="@drawable/ic_settings"
|
||||
android:background="@null"/>
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="@dimen/app_picker_width"
|
||||
android:layout_height="@dimen/app_picker_height"
|
||||
android:layout_gravity="bottom|end"
|
||||
android:layout_margin="@dimen/app_picker_fab_margin">
|
||||
|
||||
<include layout="@layout/app_picker_layout"/>
|
||||
</FrameLayout>
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
|
@ -0,0 +1,57 @@
|
|||
<?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"
|
||||
android:id="@+id/RootView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/launcher_bg_color"
|
||||
android:fitsSystemWindows="true" >
|
||||
|
||||
<GridView
|
||||
android:id="@+id/pinned_app_grid"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="@dimen/app_grid_margin_top"
|
||||
android:layout_marginStart="@dimen/app_grid_margin_left"
|
||||
android:layout_marginEnd="@dimen/app_grid_margin_right"
|
||||
android:columnWidth="@dimen/app_list_col_width"
|
||||
android:verticalSpacing="@dimen/app_list_horizontal_spacing"
|
||||
android:horizontalSpacing="@dimen/app_list_vertical_spacing"
|
||||
android:numColumns="auto_fit" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/OptionsButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom|start"
|
||||
android:layout_marginStart="@dimen/options_button_margin"
|
||||
android:layout_marginBottom="@dimen/options_button_margin"
|
||||
android:src="@drawable/ic_settings"
|
||||
android:background="@null"/>
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="@dimen/app_picker_width"
|
||||
android:layout_height="@dimen/app_picker_height"
|
||||
android:layout_gravity="bottom|end"
|
||||
android:layout_marginEnd="@dimen/app_picker_fab_margin"
|
||||
android:layout_marginBottom="@dimen/app_picker_fab_margin">
|
||||
|
||||
<include layout="@layout/app_picker_layout"/>
|
||||
</FrameLayout>
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
|
@ -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.
|
||||
-->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/app_icon"
|
||||
android:layout_width="@dimen/app_icon_width"
|
||||
android:layout_height="@dimen/app_icon_height" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/app_name"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:maxLines="1" />
|
||||
</LinearLayout>
|
|
@ -0,0 +1,34 @@
|
|||
<?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.
|
||||
-->
|
||||
|
||||
<FrameLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<GridView
|
||||
android:id="@+id/picker_app_grid"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="@dimen/app_grid_margin_top"
|
||||
android:layout_marginStart="@dimen/app_grid_margin_left"
|
||||
android:layout_marginEnd="@dimen/app_grid_margin_right"
|
||||
android:columnWidth="@dimen/app_list_col_width"
|
||||
android:verticalSpacing="@dimen/app_list_horizontal_spacing"
|
||||
android:horizontalSpacing="@dimen/app_list_vertical_spacing"
|
||||
android:numColumns="auto_fit" />
|
||||
</FrameLayout>
|
|
@ -0,0 +1,46 @@
|
|||
<?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"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<android.support.design.circularreveal.cardview.CircularRevealCardView
|
||||
android:id="@+id/FloatingSheet"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:visibility="invisible">
|
||||
|
||||
<GridView
|
||||
android:id="@+id/app_grid"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="@dimen/app_grid_margin_top"
|
||||
android:columnWidth="@dimen/app_list_col_width"
|
||||
android:verticalSpacing="@dimen/app_list_horizontal_spacing"
|
||||
android:horizontalSpacing="@dimen/app_list_vertical_spacing"
|
||||
android:numColumns="auto_fit" />
|
||||
</android.support.design.circularreveal.cardview.CircularRevealCardView>
|
||||
|
||||
<android.support.design.widget.FloatingActionButton
|
||||
android:id="@+id/FloatingActionButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom|end"
|
||||
android:src="@drawable/ic_apps"/>
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
|
@ -0,0 +1,56 @@
|
|||
<?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"
|
||||
android:id="@+id/RootView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/launcher_bg_color"
|
||||
android:fitsSystemWindows="true" >
|
||||
|
||||
<GridView
|
||||
android:id="@+id/pinned_app_grid"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="@dimen/app_grid_margin_top"
|
||||
android:layout_marginStart="@dimen/app_grid_margin_left"
|
||||
android:layout_marginEnd="@dimen/app_grid_margin_right"
|
||||
android:columnWidth="@dimen/app_list_col_width"
|
||||
android:verticalSpacing="@dimen/app_list_horizontal_spacing"
|
||||
android:horizontalSpacing="@dimen/app_list_vertical_spacing"
|
||||
android:numColumns="auto_fit" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/OptionsButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom|start"
|
||||
android:layout_marginStart="@dimen/options_button_margin"
|
||||
android:layout_marginBottom="@dimen/options_button_margin"
|
||||
android:src="@drawable/ic_settings"
|
||||
android:background="@null"/>
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="bottom|end"
|
||||
android:layout_margin="@dimen/app_picker_fab_margin">
|
||||
|
||||
<include layout="@layout/app_picker_layout"/>
|
||||
</FrameLayout>
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
|
@ -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.
|
||||
-->
|
||||
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:id="@+id/add_app_shortcut"
|
||||
android:title="@string/add_app_shortcut" />
|
||||
<item android:id="@+id/set_wallpaper"
|
||||
android:title="@string/set_wallpaper" />
|
||||
</menu>
|
|
@ -0,0 +1,22 @@
|
|||
<?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>
|
||||
<dimen name="app_picker_width">400dp</dimen>
|
||||
<dimen name="app_picker_height">400dp</dimen>
|
||||
<dimen name="app_picker_fab_margin">60dp</dimen>
|
||||
</resources>
|
|
@ -0,0 +1,22 @@
|
|||
<?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>
|
||||
<dimen name="app_picker_width">660dp</dimen>
|
||||
<dimen name="app_picker_height">660dp</dimen>
|
||||
<dimen name="app_picker_fab_margin">70dp</dimen>
|
||||
</resources>
|
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
/* //device/apps/common/assets/res/any/colors.xml
|
||||
**
|
||||
** Copyright 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="launcher_bg_color">#884e8391</color>
|
||||
</resources>
|
|
@ -0,0 +1,31 @@
|
|||
<?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>
|
||||
<dimen name="app_list_col_width">72dp</dimen>
|
||||
<dimen name="app_list_horizontal_spacing">24dp</dimen>
|
||||
<dimen name="app_list_vertical_spacing">24dp</dimen>
|
||||
<dimen name="app_icon_width">64dp</dimen>
|
||||
<dimen name="app_icon_height">64dp</dimen>
|
||||
<dimen name="app_grid_margin_top">24dp</dimen>
|
||||
<dimen name="app_grid_margin_left">8dp</dimen>
|
||||
<dimen name="app_grid_margin_right">8dp</dimen>
|
||||
|
||||
<dimen name="app_picker_width">300dp</dimen>
|
||||
<dimen name="app_picker_height">300dp</dimen>
|
||||
<dimen name="app_picker_fab_margin">20dp</dimen>
|
||||
<dimen name="options_button_margin">20dp</dimen>
|
||||
</resources>
|
|
@ -0,0 +1,25 @@
|
|||
<?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 xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="app_name">SecondaryDisplayLauncher</string>
|
||||
<string name="couldnt_launch">Couldn\'t launch the activity</string>
|
||||
<string name="add_app_shortcut">Add app shortcut</string>
|
||||
<string name="set_wallpaper">Set wallpaper</string>
|
||||
</resources>
|
|
@ -0,0 +1,30 @@
|
|||
<?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="SecondaryLauncherTheme" parent="Theme.AppCompat.Light.NoActionBar" >
|
||||
<item name="android:windowShowWallpaper">true</item>
|
||||
<item name="android:windowNoTitle">true</item>
|
||||
<item name="android:windowIsTranslucent">true</item>
|
||||
<item name="android:windowTranslucentStatus">true</item>
|
||||
<item name="android:windowTranslucentNavigation">true</item>
|
||||
<item name="android:colorBackgroundCacheHint">@null</item>
|
||||
<item name="android:windowBackground">@android:color/transparent</item>
|
||||
</style>
|
||||
</resources>
|
|
@ -0,0 +1,58 @@
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.android.launcher3;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
/** An entry that represents a single activity that can be launched. */
|
||||
public class AppEntry {
|
||||
|
||||
private String mLabel;
|
||||
private Drawable mIcon;
|
||||
private Intent mLaunchIntent;
|
||||
|
||||
AppEntry(ResolveInfo info, PackageManager packageManager) {
|
||||
mLabel = info.loadLabel(packageManager).toString();
|
||||
mIcon = info.loadIcon(packageManager);
|
||||
mLaunchIntent = new Intent();
|
||||
mLaunchIntent.setComponent(new ComponentName(info.activityInfo.packageName,
|
||||
info.activityInfo.name));
|
||||
}
|
||||
|
||||
String getLabel() {
|
||||
return mLabel;
|
||||
}
|
||||
|
||||
Drawable getIcon() {
|
||||
return mIcon;
|
||||
}
|
||||
|
||||
Intent getLaunchIntent() { return mLaunchIntent; }
|
||||
|
||||
ComponentName getComponentName() {
|
||||
return mLaunchIntent.getComponent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return mLabel;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.android.launcher3;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.launcher3.R;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/** Adapter for available apps list. */
|
||||
public class AppListAdapter extends ArrayAdapter<AppEntry> {
|
||||
private final LayoutInflater mInflater;
|
||||
|
||||
AppListAdapter(Context context) {
|
||||
super(context, android.R.layout.simple_list_item_2);
|
||||
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
}
|
||||
|
||||
void setData(List<AppEntry> data) {
|
||||
clear();
|
||||
if (data != null) {
|
||||
addAll(data);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
View view;
|
||||
|
||||
if (convertView == null) {
|
||||
view = mInflater.inflate(R.layout.app_grid_item, parent, false);
|
||||
} else {
|
||||
view = convertView;
|
||||
}
|
||||
|
||||
AppEntry item = getItem(position);
|
||||
((ImageView)view.findViewById(R.id.app_icon)).setImageDrawable(item.getIcon());
|
||||
((TextView)view.findViewById(R.id.app_name)).setText(item.getLabel());
|
||||
|
||||
return view;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,126 @@
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.android.launcher3;
|
||||
|
||||
import android.app.Application;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.os.AsyncTask;
|
||||
|
||||
import androidx.lifecycle.AndroidViewModel;
|
||||
import androidx.lifecycle.LiveData;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A view model that provides a list of activities that can be launched.
|
||||
*/
|
||||
public class AppListViewModel extends AndroidViewModel {
|
||||
|
||||
private final AppListLiveData mLiveData;
|
||||
private final PackageIntentReceiver
|
||||
mPackageIntentReceiver;
|
||||
|
||||
public AppListViewModel(Application application) {
|
||||
super(application);
|
||||
mLiveData = new AppListLiveData(application);
|
||||
mPackageIntentReceiver = new PackageIntentReceiver(mLiveData, application);
|
||||
}
|
||||
|
||||
public LiveData<List<AppEntry>> getAppList() {
|
||||
return mLiveData;
|
||||
}
|
||||
|
||||
protected void onCleared() {
|
||||
getApplication().unregisterReceiver(mPackageIntentReceiver);
|
||||
}
|
||||
}
|
||||
|
||||
class AppListLiveData extends LiveData<List<AppEntry>> {
|
||||
|
||||
private final PackageManager mPackageManager;
|
||||
private int mCurrentDataVersion;
|
||||
|
||||
public AppListLiveData(Context context) {
|
||||
mPackageManager = context.getPackageManager();
|
||||
loadData();
|
||||
}
|
||||
|
||||
void loadData() {
|
||||
final int loadDataVersion = ++mCurrentDataVersion;
|
||||
|
||||
new AsyncTask<Void, Void, List<AppEntry>>() {
|
||||
@Override
|
||||
protected List<AppEntry> doInBackground(Void... voids) {
|
||||
Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
|
||||
mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
|
||||
|
||||
List<ResolveInfo> apps = mPackageManager.queryIntentActivities(mainIntent,
|
||||
PackageManager.GET_META_DATA);
|
||||
|
||||
List<AppEntry> entries = new ArrayList<>();
|
||||
if (apps != null) {
|
||||
for (ResolveInfo app : apps) {
|
||||
AppEntry entry = new AppEntry(app, mPackageManager);
|
||||
entries.add(entry);
|
||||
}
|
||||
}
|
||||
return entries;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(List<AppEntry> data) {
|
||||
if (mCurrentDataVersion == loadDataVersion) {
|
||||
setValue(data);
|
||||
}
|
||||
}
|
||||
}.execute();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Receiver used to notify live data about app list changes.
|
||||
*/
|
||||
class PackageIntentReceiver extends BroadcastReceiver {
|
||||
|
||||
private final AppListLiveData mLiveData;
|
||||
|
||||
public PackageIntentReceiver(AppListLiveData liveData, Context context) {
|
||||
mLiveData = liveData;
|
||||
IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
|
||||
filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
|
||||
filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
|
||||
filter.addDataScheme("package");
|
||||
context.registerReceiver(this, filter);
|
||||
|
||||
// Register for events related to sdcard installation.
|
||||
IntentFilter sdFilter = new IntentFilter();
|
||||
sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
|
||||
sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
|
||||
context.registerReceiver(this, sdFilter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
mLiveData.loadData();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,120 @@
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.android.launcher3;
|
||||
|
||||
import static com.android.launcher3.PinnedAppListViewModel.PINNED_APPS_KEY;
|
||||
|
||||
import android.app.Application;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.os.AsyncTask;
|
||||
|
||||
import androidx.lifecycle.AndroidViewModel;
|
||||
import androidx.lifecycle.LiveData;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* A view model that provides a list of activities that were pinned by user to always display on
|
||||
* home screen.
|
||||
* The pinned activities are stored in {@link SharedPreferences} to keep the sample simple :).
|
||||
*/
|
||||
public class PinnedAppListViewModel extends AndroidViewModel {
|
||||
|
||||
final static String PINNED_APPS_KEY = "pinned_apps";
|
||||
|
||||
private final PinnedAppListLiveData mLiveData;
|
||||
|
||||
public PinnedAppListViewModel(Application application) {
|
||||
super(application);
|
||||
mLiveData = new PinnedAppListLiveData(application);
|
||||
}
|
||||
|
||||
public LiveData<List<AppEntry>> getPinnedAppList() {
|
||||
return mLiveData;
|
||||
}
|
||||
}
|
||||
|
||||
class PinnedAppListLiveData extends LiveData<List<AppEntry>> {
|
||||
|
||||
private final Context mContext;
|
||||
private final PackageManager mPackageManager;
|
||||
// Store listener reference, so it won't be GC-ed.
|
||||
private final SharedPreferences.OnSharedPreferenceChangeListener mChangeListener;
|
||||
private int mCurrentDataVersion;
|
||||
|
||||
public PinnedAppListLiveData(Context context) {
|
||||
mContext = context;
|
||||
mPackageManager = context.getPackageManager();
|
||||
|
||||
final SharedPreferences prefs = context.getSharedPreferences(PINNED_APPS_KEY, 0);
|
||||
mChangeListener = (preferences, key) -> {
|
||||
loadData();
|
||||
};
|
||||
prefs.registerOnSharedPreferenceChangeListener(mChangeListener);
|
||||
|
||||
loadData();
|
||||
}
|
||||
|
||||
private void loadData() {
|
||||
final int loadDataVersion = ++mCurrentDataVersion;
|
||||
|
||||
new AsyncTask<Void, Void, List<AppEntry>>() {
|
||||
@Override
|
||||
protected List<AppEntry> doInBackground(Void... voids) {
|
||||
List<AppEntry> entries = new ArrayList<>();
|
||||
|
||||
final SharedPreferences sp = mContext.getSharedPreferences(PINNED_APPS_KEY, 0);
|
||||
final Set<String> pinnedAppsComponents = sp.getStringSet(PINNED_APPS_KEY, null);
|
||||
if (pinnedAppsComponents == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
for (String componentString : pinnedAppsComponents) {
|
||||
final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
|
||||
mainIntent.setComponent(ComponentName.unflattenFromString(componentString));
|
||||
mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
|
||||
|
||||
final List<ResolveInfo> apps = mPackageManager.queryIntentActivities(mainIntent,
|
||||
PackageManager.GET_META_DATA);
|
||||
|
||||
if (apps != null) {
|
||||
for (ResolveInfo app : apps) {
|
||||
final AppEntry entry = new AppEntry(app, mPackageManager);
|
||||
entries.add(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return entries;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(List<AppEntry> data) {
|
||||
if (mCurrentDataVersion == loadDataVersion) {
|
||||
setValue(data);
|
||||
}
|
||||
}
|
||||
}.execute();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.android.launcher3;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.GridView;
|
||||
|
||||
import androidx.fragment.app.DialogFragment;
|
||||
|
||||
import com.android.launcher3.R;
|
||||
|
||||
/**
|
||||
* Callback to be invoked when an app was picked.
|
||||
*/
|
||||
interface AppPickedCallback {
|
||||
void onAppPicked(AppEntry appEntry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dialog that provides the user with a list of available apps to pin to the home screen.
|
||||
*/
|
||||
public class PinnedAppPickerDialog extends DialogFragment {
|
||||
|
||||
private AppListAdapter mAppListAdapter;
|
||||
private AppPickedCallback mAppPickerCallback;
|
||||
|
||||
public PinnedAppPickerDialog() {
|
||||
}
|
||||
|
||||
public static PinnedAppPickerDialog newInstance(AppListAdapter appListAdapter,
|
||||
AppPickedCallback callback) {
|
||||
PinnedAppPickerDialog
|
||||
frag = new PinnedAppPickerDialog();
|
||||
frag.mAppListAdapter = appListAdapter;
|
||||
frag.mAppPickerCallback = callback;
|
||||
return frag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
return inflater.inflate(R.layout.app_picker_dialog, container);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
|
||||
GridView appGridView = view.findViewById(R.id.picker_app_grid);
|
||||
appGridView.setAdapter(mAppListAdapter);
|
||||
appGridView.setOnItemClickListener((adapterView, itemView, position, id) -> {
|
||||
final AppEntry entry = mAppListAdapter.getItem(position);
|
||||
mAppPickerCallback.onAppPicked(entry);
|
||||
dismiss();
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,217 @@
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.android.launcher3;
|
||||
|
||||
import static com.android.launcher3.PinnedAppListViewModel.PINNED_APPS_KEY;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Application;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.res.Configuration;
|
||||
import android.os.Bundle;
|
||||
import android.support.design.circularreveal.cardview.CircularRevealCardView;
|
||||
import android.support.design.widget.FloatingActionButton;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewAnimationUtils;
|
||||
import android.widget.GridView;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.PopupMenu;
|
||||
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import androidx.lifecycle.ViewModelProvider.AndroidViewModelFactory;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Secondary launcher activity. It's launch mode is configured as "singleTop" to allow showing on
|
||||
* multiple displays and to ensure a single instance per each display.
|
||||
*/
|
||||
public class SecondaryDisplayLauncher extends FragmentActivity implements AppPickedCallback,
|
||||
PopupMenu.OnMenuItemClickListener {
|
||||
|
||||
private AppListAdapter mAppListAdapter;
|
||||
private AppListAdapter mPinnedAppListAdapter;
|
||||
private CircularRevealCardView mAppDrawerView;
|
||||
private FloatingActionButton mFab;
|
||||
|
||||
private boolean mAppDrawerShown;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.secondary_display_launcher);
|
||||
|
||||
mAppDrawerView = findViewById(R.id.FloatingSheet);
|
||||
mFab = findViewById(R.id.FloatingActionButton);
|
||||
|
||||
mFab.setOnClickListener((View v) -> {
|
||||
showAppDrawer(true);
|
||||
});
|
||||
|
||||
final ViewModelProvider viewModelProvider = new ViewModelProvider(getViewModelStore(),
|
||||
new AndroidViewModelFactory((Application) getApplicationContext()));
|
||||
|
||||
mPinnedAppListAdapter = new AppListAdapter(this);
|
||||
final GridView pinnedAppGridView = findViewById(R.id.pinned_app_grid);
|
||||
pinnedAppGridView.setAdapter(mPinnedAppListAdapter);
|
||||
pinnedAppGridView.setOnItemClickListener((adapterView, view, position, id) -> {
|
||||
final AppEntry entry = mPinnedAppListAdapter.getItem(position);
|
||||
launch(entry.getLaunchIntent());
|
||||
});
|
||||
final PinnedAppListViewModel pinnedAppListViewModel =
|
||||
viewModelProvider.get(PinnedAppListViewModel.class);
|
||||
pinnedAppListViewModel.getPinnedAppList().observe(this, data -> {
|
||||
mPinnedAppListAdapter.setData(data);
|
||||
});
|
||||
|
||||
mAppListAdapter = new AppListAdapter(this);
|
||||
final GridView appGridView = findViewById(R.id.app_grid);
|
||||
appGridView.setAdapter(mAppListAdapter);
|
||||
appGridView.setOnItemClickListener((adapterView, view, position, id) -> {
|
||||
final AppEntry entry = mAppListAdapter.getItem(position);
|
||||
launch(entry.getLaunchIntent());
|
||||
});
|
||||
final AppListViewModel appListViewModel = viewModelProvider.get(AppListViewModel.class);
|
||||
appListViewModel.getAppList().observe(this, data -> {
|
||||
mAppListAdapter.setData(data);
|
||||
});
|
||||
|
||||
ImageButton optionsButton = findViewById(R.id.OptionsButton);
|
||||
optionsButton.setOnClickListener((View v) -> {
|
||||
PopupMenu popup = new PopupMenu(this,v);
|
||||
popup.setOnMenuItemClickListener(this);
|
||||
MenuInflater inflater = popup.getMenuInflater();
|
||||
inflater.inflate(R.menu.context_menu, popup.getMenu());
|
||||
popup.show();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onMenuItemClick(MenuItem item) {
|
||||
// Respond to picking one of the popup menu items.
|
||||
final int id = item.getItemId();
|
||||
if (id == R.id.add_app_shortcut) {
|
||||
FragmentManager fm = getSupportFragmentManager();
|
||||
PinnedAppPickerDialog pickerDialogFragment =
|
||||
PinnedAppPickerDialog.newInstance(mAppListAdapter, this);
|
||||
pickerDialogFragment.show(fm, "fragment_app_picker");
|
||||
return true;
|
||||
} else if (id == R.id.set_wallpaper) {
|
||||
Intent intent = new Intent(Intent.ACTION_SET_WALLPAPER);
|
||||
startActivity(Intent.createChooser(intent, getString(R.string.set_wallpaper)));
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfigurationChanged(Configuration newConfig) {
|
||||
super.onConfigurationChanged(newConfig);
|
||||
showAppDrawer(false);
|
||||
}
|
||||
|
||||
public void onBackPressed() {
|
||||
// If the app drawer was shown - hide it. Otherwise, not doing anything since we don't want
|
||||
// to close the launcher.
|
||||
showAppDrawer(false);
|
||||
}
|
||||
|
||||
public void onNewIntent(Intent intent) {
|
||||
super.onNewIntent(intent);
|
||||
// A new intent will bring the launcher to top. Hide the app drawer to reset the state.
|
||||
showAppDrawer(false);
|
||||
}
|
||||
|
||||
void launch(Intent launchIntent) {
|
||||
launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
try {
|
||||
startActivity(launchIntent);
|
||||
} catch (Exception e) {
|
||||
final AlertDialog.Builder builder =
|
||||
new AlertDialog.Builder(this, android.R.style.Theme_Material_Dialog_Alert);
|
||||
builder.setTitle(R.string.couldnt_launch)
|
||||
.setMessage(e.getLocalizedMessage())
|
||||
.setIcon(android.R.drawable.ic_dialog_alert)
|
||||
.show();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Store the picked app to persistent pinned list and update the loader.
|
||||
*/
|
||||
@Override
|
||||
public void onAppPicked(AppEntry appEntry) {
|
||||
final SharedPreferences sp = getSharedPreferences(PINNED_APPS_KEY, 0);
|
||||
Set<String> pinnedApps = sp.getStringSet(PINNED_APPS_KEY, null);
|
||||
if (pinnedApps == null) {
|
||||
pinnedApps = new HashSet<String>();
|
||||
} else {
|
||||
// Always need to create a new object to make sure that the changes are persisted.
|
||||
pinnedApps = new HashSet<String>(pinnedApps);
|
||||
}
|
||||
pinnedApps.add(appEntry.getComponentName().flattenToString());
|
||||
|
||||
final SharedPreferences.Editor editor = sp.edit();
|
||||
editor.putStringSet(PINNED_APPS_KEY, pinnedApps);
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
/**
|
||||
* Show/hide app drawer card with animation.
|
||||
*/
|
||||
private void showAppDrawer(boolean show) {
|
||||
if (show == mAppDrawerShown) {
|
||||
return;
|
||||
}
|
||||
|
||||
final Animator animator = revealAnimator(mAppDrawerView, show);
|
||||
if (show) {
|
||||
mAppDrawerShown = true;
|
||||
mAppDrawerView.setVisibility(View.VISIBLE);
|
||||
mFab.setVisibility(View.INVISIBLE);
|
||||
} else {
|
||||
mAppDrawerShown = false;
|
||||
animator.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
super.onAnimationEnd(animation);
|
||||
mAppDrawerView.setVisibility(View.INVISIBLE);
|
||||
mFab.setVisibility(View.VISIBLE);
|
||||
}
|
||||
});
|
||||
}
|
||||
animator.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create reveal/hide animator for app list card.
|
||||
*/
|
||||
private Animator revealAnimator(View view, boolean open) {
|
||||
final int radius = (int) Math.hypot((double) view.getWidth(), (double) view.getHeight());
|
||||
return ViewAnimationUtils.createCircularReveal(view, view.getRight(), view.getBottom(),
|
||||
open ? 0 : radius, open ? radius : 0);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue