diff options
author | Sunny Goyal <sunnygoyal@google.com> | 2018-11-29 10:33:47 -0800 |
---|---|---|
committer | Sunny Goyal <sunnygoyal@google.com> | 2018-12-07 00:06:25 -0800 |
commit | 415f17333123eb40e7677cf0766f59e7af3f7418 (patch) | |
tree | cb2573a312e63bb0602963cf3fa20d1a69f1ee5a | |
parent | dab230f63ccf3fa184e14ffa3d10a647097d8478 (diff) | |
download | android_packages_apps_Trebuchet-415f17333123eb40e7677cf0766f59e7af3f7418.tar.gz android_packages_apps_Trebuchet-415f17333123eb40e7677cf0766f59e7af3f7418.tar.bz2 android_packages_apps_Trebuchet-415f17333123eb40e7677cf0766f59e7af3f7418.zip |
Changing the format for device profile definition
Device profiles are defined such that the grid size is fixed
and only the icon and text sizes change. For every grid size option
there are multiple display configurations.
Bug: 118758696
Change-Id: I54aac9106c576324b02530913c447e849b4ae1da
-rw-r--r-- | res/values-land/dimens.xml | 2 | ||||
-rw-r--r-- | res/values/attrs.xml | 18 | ||||
-rw-r--r-- | res/values/dimens.xml | 2 | ||||
-rw-r--r-- | res/xml/default_workspace_3x3.xml | 17 | ||||
-rw-r--r-- | res/xml/default_workspace_4x4.xml | 44 | ||||
-rw-r--r-- | res/xml/default_workspace_5x5.xml | 53 | ||||
-rw-r--r-- | res/xml/default_workspace_5x6.xml | 37 | ||||
-rw-r--r-- | res/xml/device_profiles.xml | 233 | ||||
-rw-r--r-- | res/xml/dw_phone_hotseat.xml | 70 | ||||
-rw-r--r-- | res/xml/dw_tablet_hotseat.xml | 84 | ||||
-rw-r--r-- | src/com/android/launcher3/DeviceProfile.java | 9 | ||||
-rw-r--r-- | src/com/android/launcher3/InvariantDeviceProfile.java | 285 | ||||
-rw-r--r-- | src/com/android/launcher3/Utilities.java | 16 | ||||
-rw-r--r-- | src/com/android/launcher3/model/GridSizeMigrationTask.java | 12 | ||||
-rw-r--r-- | src/com/android/launcher3/provider/ImportDataTask.java | 16 |
15 files changed, 408 insertions, 490 deletions
diff --git a/res/values-land/dimens.xml b/res/values-land/dimens.xml index f0021956a..b2f357565 100644 --- a/res/values-land/dimens.xml +++ b/res/values-land/dimens.xml @@ -31,7 +31,5 @@ <dimen name="dynamic_grid_cell_layout_bottom_padding">5.5dp</dimen> <!-- Hotseat --> - <!-- Will be set to equal the hotseat icon size. --> - <dimen name="dynamic_grid_hotseat_size">0dp</dimen> <dimen name="dynamic_grid_hotseat_side_padding">16dp</dimen> </resources> diff --git a/res/values/attrs.xml b/res/values/attrs.xml index 29bd3c887..8c4dd1efd 100644 --- a/res/values/attrs.xml +++ b/res/values/attrs.xml @@ -93,10 +93,8 @@ <attr name="layout_ignoreInsets" format="boolean" /> </declare-styleable> - <declare-styleable name="InvariantDeviceProfile"> + <declare-styleable name="GridDisplayOption"> <attr name="name" format="string" /> - <attr name="minWidthDps" format="float" /> - <attr name="minHeightDps" format="float" /> <attr name="numRows" format="integer" /> <attr name="numColumns" format="integer" /> @@ -106,13 +104,21 @@ <!-- numHotseatIcons defaults to numColumns, if not specified --> <attr name="numHotseatIcons" format="integer" /> + <attr name="defaultLayoutId" format="reference" /> + <attr name="demoModeLayoutId" format="reference" /> + </declare-styleable> + + <declare-styleable name="ProfileDisplayOption"> + <attr name="name" /> + <attr name="minWidthDps" format="float" /> + <attr name="minHeightDps" format="float" /> + <attr name="iconSize" format="float" /> <!-- landscapeIconSize defaults to iconSize, if not specified --> <attr name="landscapeIconSize" format="float" /> <attr name="iconTextSize" format="float" /> - - <attr name="defaultLayoutId" format="reference" /> - <attr name="demoModeLayoutId" format="reference" /> + <!-- If true, this display option is used to determine the default grid --> + <attr name="canBeDefault" format="boolean" /> </declare-styleable> <declare-styleable name="CellLayout"> diff --git a/res/values/dimens.xml b/res/values/dimens.xml index 8adae3618..078ce60a6 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -36,7 +36,7 @@ <dimen name="dynamic_grid_hotseat_bottom_padding">2dp</dimen> <!-- Extra bottom padding for non-tall devices. --> <dimen name="dynamic_grid_hotseat_bottom_non_tall_padding">0dp</dimen> - <dimen name="dynamic_grid_hotseat_size">80dp</dimen> + <dimen name="dynamic_grid_hotseat_extra_vertical_size">34dp</dimen> <dimen name="dynamic_grid_hotseat_side_padding">0dp</dimen> <!-- Hotseat/all-apps scrim --> diff --git a/res/xml/default_workspace_3x3.xml b/res/xml/default_workspace_3x3.xml index 8d9940450..31376e1d5 100644 --- a/res/xml/default_workspace_3x3.xml +++ b/res/xml/default_workspace_3x3.xml @@ -68,21 +68,4 @@ <favorite launcher:uri="market://details?id=com.android.launcher" /> </resolve> - <!-- Second last row --> - <resolve - launcher:screen="0" - launcher:x="0" - launcher:y="-2" > - <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_BROWSER;end" /> - <favorite launcher:uri="http://www.example.com/" /> - </resolve> - - <resolve - launcher:screen="0" - launcher:x="2" - launcher:y="-2" > - <favorite launcher:uri="#Intent;action=android.media.action.STILL_IMAGE_CAMERA;end" /> - <favorite launcher:uri="#Intent;action=android.intent.action.CAMERA_BUTTON;end" /> - </resolve> - </favorites> diff --git a/res/xml/default_workspace_4x4.xml b/res/xml/default_workspace_4x4.xml index 979a1b4c8..bf3c62c77 100644 --- a/res/xml/default_workspace_4x4.xml +++ b/res/xml/default_workspace_4x4.xml @@ -16,8 +16,48 @@ <favorites xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3"> - <!-- Hotseat --> - <include launcher:workspace="@xml/dw_phone_hotseat" /> + <!-- Hotseat (We use the screen as the position of the item in the hotseat) --> + <!-- Dialer, Messaging, Browser, Camera --> + <resolve + launcher:container="-101" + launcher:screen="0" + launcher:x="0" + launcher:y="0" > + <favorite launcher:uri="#Intent;action=android.intent.action.DIAL;end" /> + <favorite launcher:uri="tel:123" /> + <favorite launcher:uri="#Intent;action=android.intent.action.CALL_BUTTON;end" /> + </resolve> + + <resolve + launcher:container="-101" + launcher:screen="1" + launcher:x="1" + launcher:y="0" > + <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_MESSAGING;end" /> + <favorite launcher:uri="sms:" /> + <favorite launcher:uri="smsto:" /> + <favorite launcher:uri="mms:" /> + <favorite launcher:uri="mmsto:" /> + </resolve> + + <resolve + launcher:container="-101" + launcher:screen="2" + launcher:x="2" + launcher:y="0" > + <favorite + launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_BROWSER;end" /> + <favorite launcher:uri="http://www.example.com/" /> + </resolve> + + <resolve + launcher:container="-101" + launcher:screen="3" + launcher:x="3" + launcher:y="0" > + <favorite launcher:uri="#Intent;action=android.media.action.STILL_IMAGE_CAMERA;end" /> + <favorite launcher:uri="#Intent;action=android.intent.action.CAMERA_BUTTON;end" /> + </resolve> <!-- Bottom row --> <resolve diff --git a/res/xml/default_workspace_5x5.xml b/res/xml/default_workspace_5x5.xml index f9cc0e789..ccdde2ca8 100644 --- a/res/xml/default_workspace_5x5.xml +++ b/res/xml/default_workspace_5x5.xml @@ -16,8 +16,57 @@ <favorites xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3"> - <!-- Hotseat --> - <include launcher:workspace="@xml/dw_phone_hotseat" /> + <!-- Hotseat (We use the screen as the position of the item in the hotseat) --> + <!-- Dialer, Messaging, [Maps/Music], Browser, Camera --> + <resolve + launcher:container="-101" + launcher:screen="0" + launcher:x="0" + launcher:y="0" > + <favorite launcher:uri="#Intent;action=android.intent.action.DIAL;end" /> + <favorite launcher:uri="tel:123" /> + <favorite launcher:uri="#Intent;action=android.intent.action.CALL_BUTTON;end" /> + </resolve> + + <resolve + launcher:container="-101" + launcher:screen="1" + launcher:x="1" + launcher:y="0" > + <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_MESSAGING;end" /> + <favorite launcher:uri="sms:" /> + <favorite launcher:uri="smsto:" /> + <favorite launcher:uri="mms:" /> + <favorite launcher:uri="mmsto:" /> + </resolve> + + <resolve + launcher:container="-101" + launcher:screen="2" + launcher:x="2" + launcher:y="0" > + <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_MAPS;end" /> + <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_MUSIC;end" /> + </resolve> + + <resolve + launcher:container="-101" + launcher:screen="3" + launcher:x="3" + launcher:y="0" > + <favorite + launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_BROWSER;end" /> + <favorite launcher:uri="http://www.example.com/" /> + </resolve> + + <resolve + launcher:container="-101" + launcher:screen="4" + launcher:x="4" + launcher:y="0" > + <favorite launcher:uri="#Intent;action=android.media.action.STILL_IMAGE_CAMERA;end" /> + <favorite launcher:uri="#Intent;action=android.intent.action.CAMERA_BUTTON;end" /> + </resolve> <!-- Bottom row --> <resolve diff --git a/res/xml/default_workspace_5x6.xml b/res/xml/default_workspace_5x6.xml deleted file mode 100644 index 8493c265e..000000000 --- a/res/xml/default_workspace_5x6.xml +++ /dev/null @@ -1,37 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2012 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> - -<favorites xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3"> - - <!-- Hotseat --> - <include launcher:workspace="@xml/dw_tablet_hotseat" /> - - <!-- Bottom row --> - <favorite - launcher:screen="0" - launcher:x="0" - launcher:y="-1" - launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_CONTACTS;end" /> - - <resolve - launcher:screen="0" - launcher:x="-1" - launcher:y="-1" > - <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_MARKET;end" /> - <favorite launcher:uri="market://details?id=com.android.launcher" /> - </resolve> - -</favorites> diff --git a/res/xml/device_profiles.xml b/res/xml/device_profiles.xml index ef6e14506..88b1bc95a 100644 --- a/res/xml/device_profiles.xml +++ b/res/xml/device_profiles.xml @@ -17,158 +17,109 @@ <profiles xmlns:launcher="http://schemas.android.com/apk/res-auto" > - <profile - launcher:name="Super Short Stubby" - launcher:minWidthDps="255" - launcher:minHeightDps="300" - launcher:numRows="2" - launcher:numColumns="3" - launcher:numFolderRows="2" - launcher:numFolderColumns="3" - launcher:iconSize="48" - launcher:iconTextSize="13.0" - launcher:numHotseatIcons="3" - launcher:defaultLayoutId="@xml/default_workspace_3x3" - /> - - <profile - launcher:name="Shorter Stubby" - launcher:minWidthDps="255" - launcher:minHeightDps="400" + <grid-option + launcher:name="3_by_3" launcher:numRows="3" launcher:numColumns="3" - launcher:numFolderRows="3" + launcher:numFolderRows="2" launcher:numFolderColumns="3" - launcher:iconSize="48" - launcher:iconTextSize="13.0" launcher:numHotseatIcons="3" - launcher:defaultLayoutId="@xml/default_workspace_3x3" - /> - - <profile - launcher:name="Short Stubby" - launcher:minWidthDps="275" - launcher:minHeightDps="420" - launcher:numRows="3" - launcher:numColumns="4" - launcher:numFolderRows="3" - launcher:numFolderColumns="4" - launcher:iconSize="48" - launcher:iconTextSize="13.0" - launcher:numHotseatIcons="5" - launcher:defaultLayoutId="@xml/default_workspace_4x4" - /> - - <profile - launcher:name="Stubby" - launcher:minWidthDps="255" - launcher:minHeightDps="450" - launcher:numRows="3" - launcher:numColumns="4" - launcher:numFolderRows="3" - launcher:numFolderColumns="4" - launcher:iconSize="48" - launcher:iconTextSize="13.0" - launcher:numHotseatIcons="5" - launcher:defaultLayoutId="@xml/default_workspace_4x4" - /> - - <profile - launcher:name="Nexus S" - launcher:minWidthDps="296" - launcher:minHeightDps="491.33" - launcher:numRows="4" - launcher:numColumns="4" - launcher:numFolderRows="4" - launcher:numFolderColumns="4" - launcher:iconSize="48" - launcher:iconTextSize="13.0" - launcher:numHotseatIcons="5" - launcher:defaultLayoutId="@xml/default_workspace_4x4" - /> - - <profile - launcher:name="Nexus 4" - launcher:minWidthDps="359" - launcher:minHeightDps="567" + launcher:defaultLayoutId="@xml/default_workspace_3x3" > + + <display-option + launcher:name="Super Short Stubby" + launcher:minWidthDps="255" + launcher:minHeightDps="300" + launcher:iconSize="48" + launcher:iconTextSize="13.0" + launcher:canBeDefault="true" /> + + <display-option + launcher:name="Shorter Stubby" + launcher:minWidthDps="255" + launcher:minHeightDps="400" + launcher:iconSize="48" + launcher:iconTextSize="13.0" + launcher:canBeDefault="true" /> + + </grid-option> + + <grid-option + launcher:name="4_by_4" launcher:numRows="4" launcher:numColumns="4" - launcher:numFolderRows="4" - launcher:numFolderColumns="4" - launcher:iconSize="54" - launcher:iconTextSize="13.0" - launcher:numHotseatIcons="5" - launcher:defaultLayoutId="@xml/default_workspace_4x4" - /> - - <profile - launcher:name="Nexus 5" - launcher:minWidthDps="335" - launcher:minHeightDps="567" - launcher:numRows="4" - launcher:numColumns="4" - launcher:numFolderRows="4" + launcher:numFolderRows="3" launcher:numFolderColumns="4" - launcher:iconSize="54" - launcher:iconTextSize="13.0" - launcher:numHotseatIcons="5" - launcher:defaultLayoutId="@xml/default_workspace_4x4" - /> - - <profile - launcher:name="Large Phone" - launcher:minWidthDps="406" - launcher:minHeightDps="694" + launcher:numHotseatIcons="4" + launcher:defaultLayoutId="@xml/default_workspace_4x4" > + + <display-option + launcher:name="Short Stubby" + launcher:minWidthDps="275" + launcher:minHeightDps="420" + launcher:iconSize="48" + launcher:iconTextSize="13.0" + launcher:canBeDefault="true" /> + + <display-option + launcher:name="Stubby" + launcher:minWidthDps="255" + launcher:minHeightDps="450" + launcher:iconSize="48" + launcher:iconTextSize="13.0" + launcher:canBeDefault="true" /> + + <display-option + launcher:name="Nexus S" + launcher:minWidthDps="296" + launcher:minHeightDps="491.33" + launcher:iconSize="48" + launcher:iconTextSize="13.0" + launcher:canBeDefault="true" /> + + <display-option + launcher:name="Nexus 4" + launcher:minWidthDps="359" + launcher:minHeightDps="567" + launcher:iconSize="54" + launcher:iconTextSize="13.0" + launcher:canBeDefault="true" /> + + <display-option + launcher:name="Nexus 5" + launcher:minWidthDps="335" + launcher:minHeightDps="567" + launcher:iconSize="54" + launcher:iconTextSize="13.0" + launcher:canBeDefault="true" /> + + </grid-option> + + <grid-option + launcher:name="5_by_5" launcher:numRows="5" launcher:numColumns="5" launcher:numFolderRows="4" launcher:numFolderColumns="4" - launcher:iconSize="56" - launcher:iconTextSize="14.4" launcher:numHotseatIcons="5" - launcher:defaultLayoutId="@xml/default_workspace_5x5" - /> - - <profile - launcher:name="Nexus 7" - launcher:minWidthDps="575" - launcher:minHeightDps="904" - launcher:numRows="6" - launcher:numColumns="6" - launcher:numFolderRows="4" - launcher:numFolderColumns="5" - launcher:iconSize="64" - launcher:iconTextSize="14.4" - launcher:numHotseatIcons="6" - launcher:defaultLayoutId="@xml/default_workspace_5x6" - /> - - <profile - launcher:name="Nexus 10" - launcher:minWidthDps="727" - launcher:minHeightDps="1207" - launcher:numRows="6" - launcher:numColumns="7" - launcher:numFolderRows="4" - launcher:numFolderColumns="5" - launcher:iconSize="76" - launcher:iconTextSize="14.4" - launcher:numHotseatIcons="7" - launcher:defaultLayoutId="@xml/default_workspace_5x6" - /> - - <profile - launcher:name="20-inch Tablet" - launcher:minWidthDps="1527" - launcher:minHeightDps="2527" - launcher:numRows="7" - launcher:numColumns="7" - launcher:numFolderRows="6" - launcher:numFolderColumns="6" - launcher:iconSize="100" - launcher:iconTextSize="20.0" - launcher:numHotseatIcons="7" - launcher:defaultLayoutId="@xml/default_workspace_5x6" - /> + launcher:defaultLayoutId="@xml/default_workspace_5x5" > + + <display-option + launcher:name="Large Phone" + launcher:minWidthDps="406" + launcher:minHeightDps="694" + launcher:iconSize="56" + launcher:iconTextSize="14.4" + launcher:canBeDefault="true" /> + + <display-option + launcher:name="Shorter Stubby" + launcher:minWidthDps="255" + launcher:minHeightDps="400" + launcher:iconSize="48" + launcher:iconTextSize="13.0" + launcher:canBeDefault="true" /> + + </grid-option> </profiles>
\ No newline at end of file diff --git a/res/xml/dw_phone_hotseat.xml b/res/xml/dw_phone_hotseat.xml deleted file mode 100644 index c691ebc3d..000000000 --- a/res/xml/dw_phone_hotseat.xml +++ /dev/null @@ -1,70 +0,0 @@ -<?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"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> - -<favorites xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3"> - <!-- Hotseat (We use the screen as the position of the item in the hotseat) --> - <!-- Dialer, Messaging, [Maps/Music], Browser, Camera --> - <resolve - launcher:container="-101" - launcher:screen="0" - launcher:x="0" - launcher:y="0" > - <favorite launcher:uri="#Intent;action=android.intent.action.DIAL;end" /> - <favorite launcher:uri="tel:123" /> - <favorite launcher:uri="#Intent;action=android.intent.action.CALL_BUTTON;end" /> - </resolve> - - <resolve - launcher:container="-101" - launcher:screen="1" - launcher:x="1" - launcher:y="0" > - <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_MESSAGING;end" /> - <favorite launcher:uri="sms:" /> - <favorite launcher:uri="smsto:" /> - <favorite launcher:uri="mms:" /> - <favorite launcher:uri="mmsto:" /> - </resolve> - - <resolve - launcher:container="-101" - launcher:screen="2" - launcher:x="2" - launcher:y="0" > - <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_MAPS;end" /> - <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_MUSIC;end" /> - </resolve> - - <resolve - launcher:container="-101" - launcher:screen="3" - launcher:x="3" - launcher:y="0" > - <favorite - launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_BROWSER;end" /> - <favorite launcher:uri="http://www.example.com/" /> - </resolve> - - <resolve - launcher:container="-101" - launcher:screen="4" - launcher:x="4" - launcher:y="0" > - <favorite launcher:uri="#Intent;action=android.media.action.STILL_IMAGE_CAMERA;end" /> - <favorite launcher:uri="#Intent;action=android.intent.action.CAMERA_BUTTON;end" /> - </resolve> - -</favorites> diff --git a/res/xml/dw_tablet_hotseat.xml b/res/xml/dw_tablet_hotseat.xml deleted file mode 100644 index 6fe7f93d8..000000000 --- a/res/xml/dw_tablet_hotseat.xml +++ /dev/null @@ -1,84 +0,0 @@ -<?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"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> - -<favorites xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3"> - <!-- Hotseat (We use the screen as the position of the item in the hotseat) --> - <!-- Messaging, Email, Browser, Maps, Music, Gallery, Camera --> - <resolve - launcher:container="-101" - launcher:screen="0" - launcher:x="0" - launcher:y="0" > - <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_MESSAGING;end" /> - <favorite launcher:uri="sms:" /> - <favorite launcher:uri="smsto:" /> - <favorite launcher:uri="mms:" /> - <favorite launcher:uri="mmsto:" /> - </resolve> - - <resolve - launcher:container="-101" - launcher:screen="1" - launcher:x="1" - launcher:y="0" > - <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_EMAIL;end" /> - <favorite launcher:uri="mailto:" /> - </resolve> - - <resolve - launcher:container="-101" - launcher:screen="2" - launcher:x="2" - launcher:y="0" > - <favorite - launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_BROWSER;end" /> - <favorite launcher:uri="http://www.example.com/" /> - </resolve> - - <resolve - launcher:container="-101" - launcher:screen="3" - launcher:x="3" - launcher:y="0" > - <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_MAPS;end" /> - </resolve> - - <favorite - launcher:container="-101" - launcher:screen="4" - launcher:x="4" - launcher:y="0" - launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_MUSIC;end" /> - - <resolve - launcher:container="-101" - launcher:screen="5" - launcher:x="5" - launcher:y="0" > - <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_GALLERY;end" /> - <favorite launcher:uri="#Intent;type=images/*;end" /> - </resolve> - - <resolve - launcher:container="-101" - launcher:screen="6" - launcher:x="6" - launcher:y="0" > - <favorite launcher:uri="#Intent;action=android.media.action.STILL_IMAGE_CAMERA;end" /> - <favorite launcher:uri="#Intent;action=android.intent.action.CAMERA_BUTTON;end" /> - </resolve> - -</favorites> diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java index c1c12046e..812cf9f8e 100644 --- a/src/com/android/launcher3/DeviceProfile.java +++ b/src/com/android/launcher3/DeviceProfile.java @@ -207,11 +207,10 @@ public class DeviceProfile { // Add a bit of space between nav bar and hotseat in multi-window vertical bar layout. hotseatBarSidePaddingStartPx = isMultiWindowMode && isVerticalBarLayout() ? edgeMarginPx : 0; - hotseatBarSizePx = isVerticalBarLayout() - ? Utilities.pxFromDp(inv.iconSize, dm) + hotseatBarSidePaddingStartPx - + hotseatBarSidePaddingEndPx - : res.getDimensionPixelSize(R.dimen.dynamic_grid_hotseat_size) - + hotseatBarTopPaddingPx + hotseatBarBottomPaddingPx; + hotseatBarSizePx = Utilities.pxFromDp(inv.iconSize, dm) + (isVerticalBarLayout() + ? (hotseatBarSidePaddingStartPx + hotseatBarSidePaddingEndPx) + : (res.getDimensionPixelSize(R.dimen.dynamic_grid_hotseat_extra_vertical_size) + + hotseatBarTopPaddingPx + hotseatBarBottomPaddingPx)); // Calculate all of the remaining variables. updateAvailableDimensions(dm, res); diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java index 0b2f4d921..257e46c2f 100644 --- a/src/com/android/launcher3/InvariantDeviceProfile.java +++ b/src/com/android/launcher3/InvariantDeviceProfile.java @@ -24,6 +24,8 @@ import android.content.res.Configuration; import android.content.res.TypedArray; import android.content.res.XmlResourceParser; import android.graphics.Point; +import android.text.TextUtils; +import android.util.AttributeSet; import android.util.DisplayMetrics; import android.util.Log; import android.util.Xml; @@ -32,15 +34,12 @@ import android.view.WindowManager; import com.android.launcher3.util.ConfigMonitor; import com.android.launcher3.util.MainThreadInitializedObject; -import com.android.launcher3.util.Thunk; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; import androidx.annotation.VisibleForTesting; @@ -50,6 +49,8 @@ public class InvariantDeviceProfile { public static final MainThreadInitializedObject<InvariantDeviceProfile> INSTANCE = new MainThreadInitializedObject<>(InvariantDeviceProfile::new); + private static final String KEY_IDP_GRIP_NAME = "idp_grid_name"; + private static final float ICON_SIZE_DEFINED_IN_APP_DP = 48; public static final int CHANGE_FLAG_GRID = 1 << 0; @@ -63,11 +64,6 @@ public class InvariantDeviceProfile { // used to offset float not being able to express extremely small weights in extreme cases. private static float WEIGHT_EFFICIENT = 100000f; - // Profile-defining invariant properties - private String name; - private float minWidthDps; - private float minHeightDps; - /** * Number of icons per row and column in the workspace. */ @@ -90,7 +86,7 @@ public class InvariantDeviceProfile { */ public int numHotseatIcons; - int defaultLayoutId; + public int defaultLayoutId; int demoModeLayoutId; public DeviceProfile landscapeProfile; @@ -105,37 +101,26 @@ public class InvariantDeviceProfile { public InvariantDeviceProfile() {} private InvariantDeviceProfile(InvariantDeviceProfile p) { - this(p.name, p.minWidthDps, p.minHeightDps, p.numRows, p.numColumns, - p.numFolderRows, p.numFolderColumns, - p.iconSize, p.landscapeIconSize, p.iconTextSize, p.numHotseatIcons, - p.defaultLayoutId, p.demoModeLayoutId); - } - - private InvariantDeviceProfile(String n, float w, float h, int r, int c, int fr, int fc, - float is, float lis, float its, int hs, int dlId, int dmlId) { - name = n; - minWidthDps = w; - minHeightDps = h; - numRows = r; - numColumns = c; - numFolderRows = fr; - numFolderColumns = fc; - iconSize = is; - landscapeIconSize = lis; - iconTextSize = its; - numHotseatIcons = hs; - defaultLayoutId = dlId; - demoModeLayoutId = dmlId; + numRows = p.numRows; + numColumns = p.numColumns; + numFolderRows = p.numFolderRows; + numFolderColumns = p.numFolderColumns; + iconSize = p.iconSize; + landscapeIconSize = p.landscapeIconSize; + iconTextSize = p.iconTextSize; + numHotseatIcons = p.numHotseatIcons; + defaultLayoutId = p.defaultLayoutId; + demoModeLayoutId = p.demoModeLayoutId; } @TargetApi(23) private InvariantDeviceProfile(Context context) { - initGrid(context); + initGrid(context, Utilities.getPrefs(context).getString(KEY_IDP_GRIP_NAME, null)); mConfigMonitor = new ConfigMonitor(context, APPLY_CONFIG_AT_RUNTIME.get() ? this::onConfigChanged : this::killProcess); } - private void initGrid(Context context) { + private void initGrid(Context context, String gridName) { WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); Display display = wm.getDefaultDisplay(); DisplayMetrics dm = new DisplayMetrics(); @@ -145,16 +130,18 @@ public class InvariantDeviceProfile { Point largestSize = new Point(); display.getCurrentSizeRange(smallestSize, largestSize); + ArrayList<DisplayOption> allOptions = getPredefinedDeviceProfiles(context, gridName); // This guarantees that width < height - minWidthDps = Utilities.dpiFromPx(Math.min(smallestSize.x, smallestSize.y), dm); - minHeightDps = Utilities.dpiFromPx(Math.min(largestSize.x, largestSize.y), dm); - - ArrayList<InvariantDeviceProfile> closestProfiles = findClosestDeviceProfiles( - minWidthDps, minHeightDps, getPredefinedDeviceProfiles(context)); - InvariantDeviceProfile interpolatedDeviceProfileOut = - invDistWeightedInterpolate(minWidthDps, minHeightDps, closestProfiles); - - InvariantDeviceProfile closestProfile = closestProfiles.get(0); + float minWidthDps = Utilities.dpiFromPx(Math.min(smallestSize.x, smallestSize.y), dm); + float minHeightDps = Utilities.dpiFromPx(Math.min(largestSize.x, largestSize.y), dm); + // Sort the profiles based on the closeness to the device size + allOptions.sort((a, b) -> + Float.compare(dist(minWidthDps, minHeightDps, a.minWidthDps, a.minHeightDps), + dist(minWidthDps, minHeightDps, b.minWidthDps, b.minHeightDps))); + DisplayOption interpolatedDisplayOption = + invDistWeightedInterpolate(minWidthDps, minHeightDps, allOptions); + + GridOption closestProfile = allOptions.get(0).grid; numRows = closestProfile.numRows; numColumns = closestProfile.numColumns; numHotseatIcons = closestProfile.numHotseatIcons; @@ -162,11 +149,15 @@ public class InvariantDeviceProfile { demoModeLayoutId = closestProfile.demoModeLayoutId; numFolderRows = closestProfile.numFolderRows; numFolderColumns = closestProfile.numFolderColumns; + if (!closestProfile.name.equals(gridName)) { + Utilities.getPrefs(context).edit() + .putString(KEY_IDP_GRIP_NAME, closestProfile.name).apply(); + } - iconSize = interpolatedDeviceProfileOut.iconSize; - landscapeIconSize = interpolatedDeviceProfileOut.landscapeIconSize; + iconSize = interpolatedDisplayOption.iconSize; + landscapeIconSize = interpolatedDisplayOption.landscapeIconSize; iconBitmapSize = Utilities.pxFromDp(iconSize, dm); - iconTextSize = interpolatedDeviceProfileOut.iconTextSize; + iconTextSize = interpolatedDisplayOption.iconTextSize; fillResIconDpi = getLauncherIconDensity(iconBitmapSize); // If the partner customization apk contains any grid overrides, apply them @@ -210,7 +201,7 @@ public class InvariantDeviceProfile { InvariantDeviceProfile oldProfile = new InvariantDeviceProfile(this); // Re-init grid - initGrid(context); + initGrid(context, Utilities.getPrefs(context).getString(KEY_IDP_GRIP_NAME, null)); int changeFlags = 0; if (numRows != oldProfile.numRows || @@ -234,41 +225,53 @@ public class InvariantDeviceProfile { } } - ArrayList<InvariantDeviceProfile> getPredefinedDeviceProfiles(Context context) { - ArrayList<InvariantDeviceProfile> profiles = new ArrayList<>(); + static ArrayList<DisplayOption> getPredefinedDeviceProfiles(Context context, String gridName) { + ArrayList<DisplayOption> profiles = new ArrayList<>(); try (XmlResourceParser parser = context.getResources().getXml(R.xml.device_profiles)) { final int depth = parser.getDepth(); int type; while (((type = parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) { - if ((type == XmlPullParser.START_TAG) && "profile".equals(parser.getName())) { - TypedArray a = context.obtainStyledAttributes( - Xml.asAttributeSet(parser), R.styleable.InvariantDeviceProfile); - int numRows = a.getInt(R.styleable.InvariantDeviceProfile_numRows, 0); - int numColumns = a.getInt(R.styleable.InvariantDeviceProfile_numColumns, 0); - float iconSize = a.getFloat(R.styleable.InvariantDeviceProfile_iconSize, 0); - profiles.add(new InvariantDeviceProfile( - a.getString(R.styleable.InvariantDeviceProfile_name), - a.getFloat(R.styleable.InvariantDeviceProfile_minWidthDps, 0), - a.getFloat(R.styleable.InvariantDeviceProfile_minHeightDps, 0), - numRows, - numColumns, - a.getInt(R.styleable.InvariantDeviceProfile_numFolderRows, numRows), - a.getInt(R.styleable.InvariantDeviceProfile_numFolderColumns, numColumns), - iconSize, - a.getFloat(R.styleable.InvariantDeviceProfile_landscapeIconSize, iconSize), - a.getFloat(R.styleable.InvariantDeviceProfile_iconTextSize, 0), - a.getInt(R.styleable.InvariantDeviceProfile_numHotseatIcons, numColumns), - a.getResourceId(R.styleable.InvariantDeviceProfile_defaultLayoutId, 0), - a.getResourceId(R.styleable.InvariantDeviceProfile_demoModeLayoutId, 0))); - a.recycle(); + if ((type == XmlPullParser.START_TAG) && "grid-option".equals(parser.getName())) { + + GridOption gridOption = new GridOption(context, Xml.asAttributeSet(parser)); + final int displayDepth = parser.getDepth(); + while (((type = parser.next()) != XmlPullParser.END_TAG || + parser.getDepth() > displayDepth) + && type != XmlPullParser.END_DOCUMENT) { + if ((type == XmlPullParser.START_TAG) && "display-option".equals( + parser.getName())) { + profiles.add(new DisplayOption( + gridOption, context, Xml.asAttributeSet(parser))); + } + } } } } catch (IOException|XmlPullParserException e) { throw new RuntimeException(e); } - return profiles; + + ArrayList<DisplayOption> filteredProfiles = new ArrayList<>(); + if (!TextUtils.isEmpty(gridName)) { + for (DisplayOption option : profiles) { + if (gridName.equals(option.grid.name)) { + filteredProfiles.add(option); + } + } + } + if (filteredProfiles.isEmpty()) { + // No grid found, use the default options + for (DisplayOption option : profiles) { + if (option.canBeDefault) { + filteredProfiles.add(option); + } + } + } + if (filteredProfiles.isEmpty()) { + throw new RuntimeException("No display option with canBeDefault=true"); + } + return filteredProfiles; } private int getLauncherIconDensity(int requiredSize) { @@ -307,60 +310,40 @@ public class InvariantDeviceProfile { } } - @Thunk float dist(float x0, float y0, float x1, float y1) { + private static float dist(float x0, float y0, float x1, float y1) { return (float) Math.hypot(x1 - x0, y1 - y0); } /** * Returns the closest device profiles ordered by closeness to the specified width and height */ - // Package private visibility for testing. - ArrayList<InvariantDeviceProfile> findClosestDeviceProfiles( - final float width, final float height, ArrayList<InvariantDeviceProfile> points) { - - // Sort the profiles by their closeness to the dimensions - ArrayList<InvariantDeviceProfile> pointsByNearness = points; - Collections.sort(pointsByNearness, new Comparator<InvariantDeviceProfile>() { - public int compare(InvariantDeviceProfile a, InvariantDeviceProfile b) { - return Float.compare(dist(width, height, a.minWidthDps, a.minHeightDps), - dist(width, height, b.minWidthDps, b.minHeightDps)); - } - }); - - return pointsByNearness; + @VisibleForTesting + static ArrayList<DisplayOption> sortByClosenessToSize( + float width, float height, ArrayList<DisplayOption> points) { + points.sort((a, b) -> + Float.compare(dist(width, height, a.minWidthDps, a.minHeightDps), + dist(width, height, b.minWidthDps, b.minHeightDps))); + return points; } - // Package private visibility for testing. - InvariantDeviceProfile invDistWeightedInterpolate(float width, float height, - ArrayList<InvariantDeviceProfile> points) { + @VisibleForTesting + static DisplayOption invDistWeightedInterpolate(float width, float height, + ArrayList<DisplayOption> points) { float weights = 0; - InvariantDeviceProfile p = points.get(0); + DisplayOption p = points.get(0); if (dist(width, height, p.minWidthDps, p.minHeightDps) == 0) { return p; } - InvariantDeviceProfile out = new InvariantDeviceProfile(); + DisplayOption out = new DisplayOption(); for (int i = 0; i < points.size() && i < KNEARESTNEIGHBOR; ++i) { - p = new InvariantDeviceProfile(points.get(i)); + p = points.get(i); float w = weight(width, height, p.minWidthDps, p.minHeightDps, WEIGHT_POWER); weights += w; - out.add(p.multiply(w)); + out.add(new DisplayOption().add(p).multiply(w)); } - return out.multiply(1.0f/weights); - } - - private void add(InvariantDeviceProfile p) { - iconSize += p.iconSize; - landscapeIconSize += p.landscapeIconSize; - iconTextSize += p.iconTextSize; - } - - private InvariantDeviceProfile multiply(float w) { - iconSize *= w; - landscapeIconSize *= w; - iconTextSize *= w; - return this; + return out.multiply(1.0f / weights); } public DeviceProfile getDeviceProfile(Context context) { @@ -368,7 +351,7 @@ public class InvariantDeviceProfile { == Configuration.ORIENTATION_LANDSCAPE ? landscapeProfile : portraitProfile; } - private float weight(float x0, float y0, float x1, float y1, float pow) { + private static float weight(float x0, float y0, float x1, float y1, float pow) { float d = dist(x0, y0, x1, y1); if (Float.compare(d, 0f) == 0) { return Float.POSITIVE_INFINITY; @@ -409,4 +392,94 @@ public class InvariantDeviceProfile { void onIdpChanged(int changeFlags, InvariantDeviceProfile profile); } + + + private static final class GridOption { + + private final String name; + private final int numRows; + private final int numColumns; + + private final int numFolderRows; + private final int numFolderColumns; + + private final int numHotseatIcons; + + private final int defaultLayoutId; + private final int demoModeLayoutId; + + GridOption(Context context, AttributeSet attrs) { + TypedArray a = context.obtainStyledAttributes( + attrs, R.styleable.GridDisplayOption); + name = a.getString(R.styleable.GridDisplayOption_name); + numRows = a.getInt(R.styleable.GridDisplayOption_numRows, 0); + numColumns = a.getInt(R.styleable.GridDisplayOption_numColumns, 0); + + defaultLayoutId = a.getResourceId( + R.styleable.GridDisplayOption_defaultLayoutId, 0); + demoModeLayoutId = a.getResourceId( + R.styleable.GridDisplayOption_demoModeLayoutId, defaultLayoutId); + numHotseatIcons = a.getInt( + R.styleable.GridDisplayOption_numHotseatIcons, numColumns); + numFolderRows = a.getInt( + R.styleable.GridDisplayOption_numFolderRows, numRows); + numFolderColumns = a.getInt( + R.styleable.GridDisplayOption_numFolderColumns, numColumns); + a.recycle(); + } + } + + private static final class DisplayOption { + private final GridOption grid; + + private final String name; + private final float minWidthDps; + private final float minHeightDps; + private final boolean canBeDefault; + + private float iconSize; + private float landscapeIconSize; + private float iconTextSize; + + DisplayOption(GridOption grid, Context context, AttributeSet attrs) { + this.grid = grid; + + TypedArray a = context.obtainStyledAttributes( + attrs, R.styleable.ProfileDisplayOption); + + name = a.getString(R.styleable.ProfileDisplayOption_name); + minWidthDps = a.getFloat(R.styleable.ProfileDisplayOption_minWidthDps, 0); + minHeightDps = a.getFloat(R.styleable.ProfileDisplayOption_minHeightDps, 0); + canBeDefault = a.getBoolean( + R.styleable.ProfileDisplayOption_canBeDefault, false); + + iconSize = a.getFloat(R.styleable.ProfileDisplayOption_iconSize, 0); + landscapeIconSize = a.getFloat(R.styleable.ProfileDisplayOption_landscapeIconSize, + iconSize); + iconTextSize = a.getFloat(R.styleable.ProfileDisplayOption_iconTextSize, 0); + a.recycle(); + } + + DisplayOption() { + grid = null; + name = null; + minWidthDps = 0; + minHeightDps = 0; + canBeDefault = false; + } + + private DisplayOption multiply(float w) { + iconSize *= w; + landscapeIconSize *= w; + iconTextSize *= w; + return this; + } + + private DisplayOption add(DisplayOption p) { + iconSize += p.iconSize; + landscapeIconSize += p.landscapeIconSize; + iconTextSize += p.iconTextSize; + return this; + } + } }
\ No newline at end of file diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java index 65f070327..a0f005c43 100644 --- a/src/com/android/launcher3/Utilities.java +++ b/src/com/android/launcher3/Utilities.java @@ -31,6 +31,7 @@ import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.Matrix; import android.graphics.Paint; +import android.graphics.Point; import android.graphics.Rect; import android.graphics.RectF; import android.os.Build; @@ -587,6 +588,21 @@ public final class Utilities { handler.sendMessage(msg); } + /** + * Parses a string encoded using {@link #getPointString(int, int)} + */ + public static Point parsePoint(String point) { + String[] split = point.split(","); + return new Point(Integer.parseInt(split[0]), Integer.parseInt(split[1])); + } + + /** + * Encodes a point to string to that it can be persisted atomically. + */ + public static String getPointString(int x, int y) { + return String.format(Locale.ENGLISH, "%d,%d", x, y); + } + public interface Consumer<T> { void accept(T var1); } diff --git a/src/com/android/launcher3/model/GridSizeMigrationTask.java b/src/com/android/launcher3/model/GridSizeMigrationTask.java index 2c1aa745f..289de1a4b 100644 --- a/src/com/android/launcher3/model/GridSizeMigrationTask.java +++ b/src/com/android/launcher3/model/GridSizeMigrationTask.java @@ -1,5 +1,8 @@ package com.android.launcher3.model; +import static com.android.launcher3.Utilities.getPointString; +import static com.android.launcher3.Utilities.parsePoint; + import android.content.ComponentName; import android.content.ContentProviderOperation; import android.content.ContentValues; @@ -877,15 +880,6 @@ public class GridSizeMigrationTask { return dup; } - private static Point parsePoint(String point) { - String[] split = point.split(","); - return new Point(Integer.parseInt(split[0]), Integer.parseInt(split[1])); - } - - private static String getPointString(int x, int y) { - return String.format(Locale.ENGLISH, "%d,%d", x, y); - } - public static void markForMigration( Context context, int gridX, int gridY, int hotseatSize) { Utilities.getPrefs(context).edit() diff --git a/src/com/android/launcher3/provider/ImportDataTask.java b/src/com/android/launcher3/provider/ImportDataTask.java index e1b26980c..b389b145d 100644 --- a/src/com/android/launcher3/provider/ImportDataTask.java +++ b/src/com/android/launcher3/provider/ImportDataTask.java @@ -44,7 +44,6 @@ import com.android.launcher3.LauncherSettings; import com.android.launcher3.LauncherSettings.Favorites; import com.android.launcher3.LauncherSettings.Settings; import com.android.launcher3.LauncherSettings.WorkspaceScreens; -import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.Workspace; import com.android.launcher3.compat.UserManagerCompat; @@ -378,18 +377,13 @@ public class ImportDataTask { return false; } - private static int getMyHotseatLayoutId(Context context) { - return LauncherAppState.getIDP(context).numHotseatIcons <= 5 - ? R.xml.dw_phone_hotseat - : R.xml.dw_tablet_hotseat; - } - /** * Extension of {@link DefaultLayoutParser} which only allows icons and shortcuts. */ private static class HotseatLayoutParser extends DefaultLayoutParser { public HotseatLayoutParser(Context context, LayoutParserCallback callback) { - super(context, null, callback, context.getResources(), getMyHotseatLayoutId(context)); + super(context, null, callback, context.getResources(), + LauncherAppState.getIDP(context).defaultLayoutId); } @Override @@ -434,6 +428,12 @@ public class ImportDataTask { // No need to add more items. return 0; } + if (!Integer.valueOf(Favorites.CONTAINER_HOTSEAT) + .equals(values.getAsInteger(Favorites.CONTAINER))) { + // Ignore items which are not for hotseat. + return 0; + } + Intent intent; try { intent = Intent.parseUri(values.getAsString(Favorites.INTENT), 0); |