diff options
-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); |