diff --git a/Android.mk b/Android.mk index e492f4a640f..9a86bdb26f1 100644 --- a/Android.mk +++ b/Android.mk @@ -208,6 +208,7 @@ else LOCAL_MIN_SDK_VERSION := 26 endif LOCAL_PACKAGE_NAME := TrebuchetQuickStep +LOCAL_CERTIFICATE := platform LOCAL_PRIVILEGED_MODULE := true LOCAL_PRODUCT_MODULE := true LOCAL_OVERRIDES_PACKAGES := Home Launcher2 Launcher3 Launcher3QuickStep diff --git a/AndroidManifest-common.xml b/AndroidManifest-common.xml index 43c08c3cd24..5aa34b8225d 100644 --- a/AndroidManifest-common.xml +++ b/AndroidManifest-common.xml @@ -47,6 +47,8 @@ + + + android:topLeftRadius="?android:attr/dialogCornerRadius" + android:bottomLeftRadius="?android:attr/dialogCornerRadius" + android:bottomRightRadius="?android:attr/dialogCornerRadius" /> diff --git a/quickstep/res/layout/digital_wellbeing_toast.xml b/quickstep/res/layout/digital_wellbeing_toast.xml index 83594e4ff33..b17b25d5b67 100644 --- a/quickstep/res/layout/digital_wellbeing_toast.xml +++ b/quickstep/res/layout/digital_wellbeing_toast.xml @@ -19,7 +19,7 @@ android:layout_width="match_parent" android:layout_height="48dp" android:background="@drawable/bg_wellbeing_toast" - android:fontFamily="sans-serif" + android:fontFamily="@*android:string/config_bodyFontFamily" android:forceHasOverlappingRendering="false" android:gravity="center" android:importantForAccessibility="noHideDescendants" diff --git a/quickstep/res/layout/task.xml b/quickstep/res/layout/task.xml index 60cfa0cbaa4..468aa9dd4a1 100644 --- a/quickstep/res/layout/task.xml +++ b/quickstep/res/layout/task.xml @@ -18,20 +18,55 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:defaultFocusHighlightEnabled="false" - android:elevation="4dp" + android:orientation="vertical" android:focusable="true"> + + + + + + + + + + android:elevation="4dp" /> - - \ No newline at end of file + diff --git a/quickstep/res/layout/task_menu.xml b/quickstep/res/layout/task_menu.xml index 098b34fcbf4..d504b7f66c9 100644 --- a/quickstep/res/layout/task_menu.xml +++ b/quickstep/res/layout/task_menu.xml @@ -16,39 +16,19 @@ --> - - - - - \ No newline at end of file + diff --git a/quickstep/res/layout/task_view_menu_option.xml b/quickstep/res/layout/task_view_menu_option.xml index 102ae9bc233..0ecd50db1ae 100644 --- a/quickstep/res/layout/task_view_menu_option.xml +++ b/quickstep/res/layout/task_view_menu_option.xml @@ -18,10 +18,13 @@ xmlns:android="http://schemas.android.com/apk/res/android" style="@style/TaskMenu.Option" android:layout_height="wrap_content" - android:layout_gravity="center" - android:orientation="vertical" + android:layout_gravity="center_horizontal|start" + android:gravity="center" + android:orientation="horizontal" android:paddingTop="@dimen/task_card_menu_option_vertical_padding" android:paddingBottom="@dimen/task_card_menu_option_vertical_padding" + android:paddingStart="@dimen/task_card_menu_option_horizontal_padding" + android:paddingEnd="@dimen/task_card_menu_option_horizontal_padding" android:background="?android:attr/selectableItemBackground" android:theme="@style/PopupItem" > @@ -29,22 +32,18 @@ android:id="@+id/icon" android:layout_width="@dimen/system_shortcut_icon_size" android:layout_height="@dimen/system_shortcut_icon_size" - android:layout_marginTop="@dimen/system_shortcut_header_icon_padding" - android:layout_marginBottom="@dimen/deep_shortcut_drawable_padding" - android:layout_gravity="center_horizontal" + android:layout_margin="@dimen/deep_shortcut_drawable_padding" android:backgroundTint="?android:attr/textColorTertiary"/> diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml index 78424ca5168..2c4a114f43f 100644 --- a/quickstep/res/values/dimens.xml +++ b/quickstep/res/values/dimens.xml @@ -16,9 +16,9 @@ - 24dp - 12dp - 48dp + 44dp + 22dp + 36dp 2dp @@ -53,6 +53,7 @@ in various configurations --> 40dp 8dp + 8dp 3dp 0dp 136dp diff --git a/quickstep/res/values/styles.xml b/quickstep/res/values/styles.xml index bb364ff6de7..ecf8c8db8a2 100644 --- a/quickstep/res/values/styles.xml +++ b/quickstep/res/values/styles.xml @@ -22,7 +22,7 @@ - \ No newline at end of file + diff --git a/quickstep/src/com/android/quickstep/util/LayoutUtils.java b/quickstep/src/com/android/quickstep/util/LayoutUtils.java index 2e118b44dfd..a3bc2beac91 100644 --- a/quickstep/src/com/android/quickstep/util/LayoutUtils.java +++ b/quickstep/src/com/android/quickstep/util/LayoutUtils.java @@ -105,6 +105,8 @@ public static void calculateTaskSize(Context context, DeviceProfile dp, } float topIconMargin = res.getDimension(R.dimen.task_thumbnail_top_margin); + // Add extra spacing for the icon + title + topIconMargin += res.getDimension(R.dimen.task_thumbnail_icon_size); float paddingVert = res.getDimension(R.dimen.task_card_vert_space); // Note this should be same as dp.availableWidthPx and dp.availableHeightPx unless diff --git a/res/drawable/bg_all_apps_searchbox.xml b/res/drawable/bg_all_apps_searchbox.xml index c3249279af2..ecfa9dc888e 100644 --- a/res/drawable/bg_all_apps_searchbox.xml +++ b/res/drawable/bg_all_apps_searchbox.xml @@ -14,6 +14,6 @@ limitations under the License. --> - - - \ No newline at end of file + + + diff --git a/res/drawable/ic_app_info_icon_pack.xml b/res/drawable/ic_app_info_icon_pack.xml new file mode 100644 index 00000000000..4a809b14ed0 --- /dev/null +++ b/res/drawable/ic_app_info_icon_pack.xml @@ -0,0 +1,15 @@ + + + + + diff --git a/res/drawable/ic_app_info_last_update.xml b/res/drawable/ic_app_info_last_update.xml new file mode 100644 index 00000000000..bc51923d794 --- /dev/null +++ b/res/drawable/ic_app_info_last_update.xml @@ -0,0 +1,10 @@ + + + diff --git a/res/drawable/ic_app_info_source.xml b/res/drawable/ic_app_info_source.xml new file mode 100644 index 00000000000..2aafd6068d7 --- /dev/null +++ b/res/drawable/ic_app_info_source.xml @@ -0,0 +1,10 @@ + + + diff --git a/res/drawable/ic_app_info_version.xml b/res/drawable/ic_app_info_version.xml new file mode 100644 index 00000000000..e3fd7bdf7ac --- /dev/null +++ b/res/drawable/ic_app_info_version.xml @@ -0,0 +1,10 @@ + + + diff --git a/res/layout/all_apps_empty_search.xml b/res/layout/all_apps_empty_search.xml index 463adac0c6e..d108fc764aa 100644 --- a/res/layout/all_apps_empty_search.xml +++ b/res/layout/all_apps_empty_search.xml @@ -23,7 +23,7 @@ android:paddingBottom="8dp" android:paddingLeft="16dp" android:paddingRight="16dp" - android:fontFamily="sans-serif-medium" + android:fontFamily="@*android:string/config_headlineFontFamilyMedium" android:textSize="14sp" android:textColor="?android:attr/textColorTertiary" android:focusable="false" /> diff --git a/res/layout/all_apps_search_market.xml b/res/layout/all_apps_search_market.xml index 6f2dd3d21e1..a9d0df7d350 100644 --- a/res/layout/all_apps_search_market.xml +++ b/res/layout/all_apps_search_market.xml @@ -21,7 +21,7 @@ android:gravity="center" android:paddingLeft="@dimen/dynamic_grid_edge_margin" android:paddingRight="@dimen/dynamic_grid_edge_margin" - android:fontFamily="sans-serif-medium" + android:fontFamily="@*android:string/config_headlineFontFamilyMedium" android:textSize="14sp" android:textColor="?android:attr/colorAccent" android:text="@string/all_apps_search_market_message" diff --git a/res/layout/app_info_bottom_sheet.xml b/res/layout/app_info_bottom_sheet.xml new file mode 100644 index 00000000000..f3dd4f79370 --- /dev/null +++ b/res/layout/app_info_bottom_sheet.xml @@ -0,0 +1,42 @@ + + + + + + + + + + \ No newline at end of file diff --git a/res/layout/drop_target_tool_tip.xml b/res/layout/drop_target_tool_tip.xml index a3efec4e312..3daedbb582b 100644 --- a/res/layout/drop_target_tool_tip.xml +++ b/res/layout/drop_target_tool_tip.xml @@ -27,5 +27,5 @@ android:paddingStart="16dp" android:paddingTop="6.5dp" android:textSize="14sp" - android:fontFamily="sans-serif" + android:fontFamily="@*android:string/config_headlineFontFamily" android:textColor="?android:attr/colorForeground" /> diff --git a/res/layout/notification_content.xml b/res/layout/notification_content.xml index d01be019eb5..8d05493a628 100644 --- a/res/layout/notification_content.xml +++ b/res/layout/notification_content.xml @@ -40,7 +40,7 @@ android:layout_width="@dimen/notification_icon_size" android:layout_height="match_parent" android:layout_gravity="end" - android:fontFamily="sans-serif-medium" + android:fontFamily="@*android:string/config_headlineFontFamilyMedium" android:gravity="center" android:textColor="?android:attr/textColorPrimary" android:textSize="@dimen/notification_header_count_text_size" /> @@ -69,7 +69,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:ellipsize="end" - android:fontFamily="sans-serif" + android:fontFamily="@*android:string/config_headlineFontFamily" android:lines="1" android:textAlignment="viewStart" android:textColor="?android:attr/textColorPrimary" @@ -80,7 +80,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:ellipsize="end" - android:fontFamily="sans-serif" + android:fontFamily="@*android:string/config_bodyFontFamily" android:lines="1" android:textColor="?android:attr/textColorSecondary" android:textSize="@dimen/notification_main_text_size" /> diff --git a/res/layout/user_folder_icon_normalized.xml b/res/layout/user_folder_icon_normalized.xml index a1033f06ce1..fb238fc64d4 100644 --- a/res/layout/user_folder_icon_normalized.xml +++ b/res/layout/user_folder_icon_normalized.xml @@ -48,7 +48,7 @@ android:layout_gravity="center_vertical" android:layout_weight="1" android:background="@android:color/transparent" - android:fontFamily="sans-serif-condensed" + android:fontFamily="@*android:string/config_bodyFontFamily" android:textStyle="bold" android:gravity="center_horizontal" android:hint="@string/folder_hint_text" diff --git a/res/layout/widgets_bottom_sheet.xml b/res/layout/widgets_bottom_sheet.xml index 3fdfc966675..3dea043fb85 100644 --- a/res/layout/widgets_bottom_sheet.xml +++ b/res/layout/widgets_bottom_sheet.xml @@ -39,7 +39,7 @@ android:layout_height="wrap_content" android:gravity="center_horizontal" android:paddingTop="4dp" - android:fontFamily="sans-serif" + android:fontFamily="@*android:string/config_bodyFontFamily" android:textColor="?android:attr/textColorTertiary" android:textSize="14sp" android:text="@string/long_press_widget_to_add"/> diff --git a/res/values-night-v26/colors.xml b/res/values-night-v26/colors.xml new file mode 100644 index 00000000000..3ed1b1878b1 --- /dev/null +++ b/res/values-night-v26/colors.xml @@ -0,0 +1,24 @@ + + + + @*android:color/primary_dark_device_default_settings + @*android:color/primary_device_default_settings + @color/omni_color1 + diff --git a/res/values-night-v26/styles.xml b/res/values-night-v26/styles.xml index 510e1f4cd01..d033ca5af85 100644 --- a/res/values-night-v26/styles.xml +++ b/res/values-night-v26/styles.xml @@ -23,4 +23,37 @@ @style/WidgetContainerTheme.Dark - \ No newline at end of file + + + + + + diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml index bb4834f69d0..243bab68928 100644 --- a/res/values-pt/strings.xml +++ b/res/values-pt/strings.xml @@ -34,7 +34,7 @@ "%1$d de largura por %2$d de altura" "Toque e mantenha pressionado para mover manualmente" "Adicionar automaticamente" - "Apps de pesquisa" + "Pesquisar apps" "Carregando apps…" "Nenhum app encontrado que corresponda a \"%1$s\"" "Pesquisar mais apps" diff --git a/res/values-v26/styles.xml b/res/values-v26/styles.xml index 8fb408b5842..2fa4fbbe435 100644 --- a/res/values-v26/styles.xml +++ b/res/values-v26/styles.xml @@ -22,9 +22,5 @@ #E8EAED ?android:attr/textColorSecondary - diff --git a/res/values/colors.xml b/res/values/colors.xml index 3c8fe1e2536..0ee15f01539 100644 --- a/res/values/colors.xml +++ b/res/values/colors.xml @@ -35,6 +35,8 @@ #E0E0E0 + @android:color/white + #E5E5E5 #9AA0A6 diff --git a/res/values/config.xml b/res/values/config.xml index b3e07e28f9c..56fd75ee6e1 100644 --- a/res/values/config.xml +++ b/res/values/config.xml @@ -69,7 +69,7 @@ - + com.android.launcher3.customization.ShadeShortcutFactory diff --git a/res/values/dimens.xml b/res/values/dimens.xml index d9b0f9a0b86..1a53832d334 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -38,7 +38,7 @@ 4dp - 24dp + 20dp 0dp @@ -79,7 +79,7 @@ 475dp 50dp 2dp - 36dp + 60dp 16dp 20dp 12dp diff --git a/res/values/lineage_strings.xml b/res/values/lineage_strings.xml index 40200b4ef57..58d1448d820 100644 --- a/res/values/lineage_strings.xml +++ b/res/values/lineage_strings.xml @@ -60,4 +60,20 @@ Default Install more There\'s no available app store + + + Double tap to sleep + Double tap on empty space for power-off + + + Swipe down to close app info. + %1$s (%2$d) + Loading... + Icon pack + None + Source + Unknown + Last update + Version + More diff --git a/res/values/styles.xml b/res/values/styles.xml index 80c791c5891..41f2e8af777 100644 --- a/res/values/styles.xml +++ b/res/values/styles.xml @@ -48,7 +48,7 @@ #CDFFFFFF ?android:attr/colorPrimary #FF212121 - #CCFFFFFF + #CCFFFFFFf false false @@ -58,7 +58,7 @@ @@ -86,12 +86,12 @@ #EA212121 102 #80000000 - #3C4043 - #5F6368 - #757575 + @*android:color/primary_dark_material_settings + @*android:color/secondary_material_settings + @*android:color/tertiary_material_settings @style/WidgetContainerTheme.Dark #FF464646 - #DD3C4043 + @*android:color/primary_dark_material_settings #FF80868B @android:color/white true @@ -106,7 +106,7 @@ + + + + + + + + + + + + + + diff --git a/res/xml/launcher_preferences.xml b/res/xml/launcher_preferences.xml index 87ffb465ca4..b7c61055f0c 100644 --- a/res/xml/launcher_preferences.xml +++ b/res/xml/launcher_preferences.xml @@ -41,6 +41,13 @@ android:title="@string/settings_edit_allow_title" android:summaryOn="@string/settings_edit_allow_summary_on" android:summaryOff="@string/settings_edit_allow_summary_off" /> + + findSystemApk(String action, PackageManager pm) { + final Intent intent = new Intent(action); + for (ResolveInfo info : pm.queryBroadcastReceivers(intent, 0)) { + if (info.activityInfo != null && + (info.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { + final String packageName = info.activityInfo.packageName; + try { + final Resources res = pm.getResourcesForApplication(packageName); + return Pair.create(packageName, res); + } catch (NameNotFoundException e) { + Log.w(TAG, "Failed to find resources for " + packageName); + } + } + } + return null; + } + /** * Trims the string, removing all whitespace at the beginning and end of the string. * Non-breaking whitespaces are also removed. diff --git a/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java b/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java index bcfdf916bbc..627b2225fd5 100644 --- a/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java +++ b/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java @@ -20,6 +20,7 @@ import static android.view.View.MeasureSpec.makeMeasureSpec; import static com.android.launcher3.LauncherState.ALL_APPS_HEADER; +import static com.android.launcher3.LauncherState.ALL_APPS_HEADER_EXTRA; import static com.android.launcher3.Utilities.prefixTextWithIcon; import static com.android.launcher3.icons.IconNormalizer.ICON_VISIBLE_AREA_FACTOR; @@ -233,6 +234,9 @@ public float getScrollRangeDelta(Rect insets) { @Override public void setContentVisibility(int visibleElements, PropertySetter setter, Interpolator interpolator) { - setter.setViewAlpha(this, (visibleElements & ALL_APPS_HEADER) != 0 ? 1 : 0, interpolator); + boolean hasAllAppsHeaderExtra = mAppsView != null + && mAppsView.getFloatingHeaderView().hasVisibleContent(); + int headerElement = hasAllAppsHeaderExtra ? ALL_APPS_HEADER_EXTRA : ALL_APPS_HEADER; + setter.setViewAlpha(this, (visibleElements & headerElement) != 0 ? 1 : 0, interpolator); } } diff --git a/src/com/android/launcher3/config/BaseFlags.java b/src/com/android/launcher3/config/BaseFlags.java index 65cf1216daf..82a2568db71 100644 --- a/src/com/android/launcher3/config/BaseFlags.java +++ b/src/com/android/launcher3/config/BaseFlags.java @@ -65,7 +65,7 @@ public static boolean showFlagTogglerUi(Context context) { // When enabled a promise icon is added to the home screen when install session is active. public static final TogglableFlag PROMISE_APPS_NEW_INSTALLS = - new TogglableFlag("PROMISE_APPS_NEW_INSTALLS", true, + new TogglableFlag("PROMISE_APPS_NEW_INSTALLS", false, "Adds a promise icon to the home screen for new install sessions."); // Enable moving the QSB on the 0th screen of the workspace diff --git a/src/com/android/launcher3/customization/InfoBottomSheet.java b/src/com/android/launcher3/customization/InfoBottomSheet.java new file mode 100644 index 00000000000..050fe226cda --- /dev/null +++ b/src/com/android/launcher3/customization/InfoBottomSheet.java @@ -0,0 +1,142 @@ +package com.android.launcher3.customization; + +import android.app.Fragment; +import android.app.FragmentManager; +import android.content.ComponentName; +import android.content.Context; +import android.os.Bundle; +import androidx.preference.Preference; +import androidx.preference.PreferenceFragment; +import androidx.recyclerview.widget.RecyclerView; + +import android.util.AttributeSet; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import com.android.launcher3.ItemInfo; +import com.android.launcher3.Launcher; +import com.android.launcher3.R; +import com.android.launcher3.util.ComponentKey; +import com.android.launcher3.widget.WidgetsBottomSheet; + +public class InfoBottomSheet extends WidgetsBottomSheet { + private final FragmentManager mFragmentManager; + private View.OnClickListener mOnAppInfoClick; + + public InfoBottomSheet(Context context) { + this(context, null); + } + + public InfoBottomSheet(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public InfoBottomSheet(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + mFragmentManager = Launcher.getLauncher(context).getFragmentManager(); + } + + public void setOnAppInfoClick(View.OnClickListener onclick) { + mOnAppInfoClick = onclick; + } + + @Override + public void populateAndShow(ItemInfo itemInfo) { + super.populateAndShow(itemInfo); + TextView title = findViewById(R.id.title); + title.setText(itemInfo.title); + + // Use a proxy so we can update the reference at runtime. + View.OnClickListener l = v -> mOnAppInfoClick.onClick(v); + + PrefsFragment fragment = + (PrefsFragment) mFragmentManager.findFragmentById(R.id.sheet_prefs); + fragment.loadForApp(itemInfo, l); + } + + @Override + public void onDetachedFromWindow() { + Fragment pf = mFragmentManager.findFragmentById(R.id.sheet_prefs); + if (pf != null) { + mFragmentManager.beginTransaction() + .remove(pf) + .commitAllowingStateLoss(); + } + super.onDetachedFromWindow(); + } + + @Override + public void onWidgetsBound() { + } + + public static class PrefsFragment extends PreferenceFragment + implements Preference.OnPreferenceChangeListener, Preference.OnPreferenceClickListener { + private static final String KEY_ICON_PACK = "pref_app_info_icon_pack"; + private static final String KEY_SOURCE = "pref_app_info_source"; + private static final String KEY_LAST_UPDATE = "pref_app_info_last_update"; + private static final String KEY_VERSION = "pref_app_info_version"; + private static final String KEY_MORE = "pref_app_info_more"; + + private Context mContext; + + private ComponentName mComponent; + private ComponentKey mKey; + private View.OnClickListener mOnMoreClick; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + mContext = getActivity(); + } + + @Override + public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { + addPreferencesFromResource(R.xml.app_info_preferences); + } + + @Override + public RecyclerView onCreateRecyclerView(LayoutInflater inflater, ViewGroup parent, + Bundle savedInstanceState) { + RecyclerView view = super.onCreateRecyclerView(inflater, parent, savedInstanceState); + view.setOverScrollMode(View.OVER_SCROLL_NEVER); + return view; + } + + public void loadForApp(ItemInfo itemInfo, final View.OnClickListener onMoreClick) { + mComponent = itemInfo.getTargetComponent(); + mKey = new ComponentKey(mComponent, itemInfo.user); + mOnMoreClick = onMoreClick; + + MetadataExtractor extractor = new MetadataExtractor(mContext, mComponent); + + Preference iconPack = findPreference(KEY_ICON_PACK); + iconPack.setOnPreferenceChangeListener(this); + iconPack.setSummary(R.string.app_info_icon_pack_none); + findPreference(KEY_SOURCE).setSummary(extractor.getSource()); + findPreference(KEY_LAST_UPDATE).setSummary(extractor.getLastUpdate()); + findPreference(KEY_VERSION).setSummary(mContext.getString( + R.string.app_info_version_value, + extractor.getVersionName(), + extractor.getVersionCode())); + findPreference(KEY_MORE).setOnPreferenceClickListener(this); + } + + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + if (KEY_ICON_PACK.equals(preference.getKey())) { + // Reload in launcher. + } + return false; + } + + @Override + public boolean onPreferenceClick(Preference preference) { + if (KEY_MORE.equals(preference.getKey())) { + mOnMoreClick.onClick(getView()); + } + return false; + } + } +} diff --git a/src/com/android/launcher3/customization/MetadataExtractor.java b/src/com/android/launcher3/customization/MetadataExtractor.java new file mode 100644 index 00000000000..51c3260f455 --- /dev/null +++ b/src/com/android/launcher3/customization/MetadataExtractor.java @@ -0,0 +1,73 @@ +package com.android.launcher3.customization; + +import android.content.ComponentName; +import android.content.Context; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.text.TextUtils; +import android.text.format.DateUtils; + +import com.android.launcher3.R; +import com.android.launcher3.Utilities; + +import java.io.File; + +import static android.content.pm.PackageManager.GET_META_DATA; + +class MetadataExtractor { + private final Context mContext; + private final PackageManager mPm; + + private String mSourcePkg = ""; + private long mLastUpdate = 0; + private String mVersionName = "Unknown"; + private long mVersionCode = 0; + + MetadataExtractor(Context context, ComponentName cn) { + mContext = context; + mPm = context.getPackageManager(); + String pkg = cn.getPackageName(); + + try { + mSourcePkg = mPm.getInstallerPackageName(pkg); + } catch (IllegalArgumentException e) { + e.printStackTrace(); + } + + try { + PackageInfo pi = mPm.getPackageInfo(pkg, GET_META_DATA); + mLastUpdate = new File(pi.applicationInfo.sourceDir).lastModified(); + mVersionName = pi.versionName; + mVersionCode = Utilities.ATLEAST_P ? pi.getLongVersionCode() : pi.versionCode; + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + } + } + + CharSequence getSource() { + if (TextUtils.isEmpty(mSourcePkg)) { + return mContext.getString(R.string.app_info_source_unknown); + } + try { + ApplicationInfo pi = mPm.getApplicationInfo(mSourcePkg, 0); + return pi.loadLabel(mPm); + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + } + return mSourcePkg; + } + + String getLastUpdate() { + return DateUtils.formatDateTime(mContext, mLastUpdate, + DateUtils.FORMAT_SHOW_WEEKDAY | DateUtils.FORMAT_SHOW_DATE); + } + + String getVersionName() { + return mVersionName; + } + + long getVersionCode() { + return mVersionCode; + } +} diff --git a/src/com/android/launcher3/customization/ShadeShortcutFactory.java b/src/com/android/launcher3/customization/ShadeShortcutFactory.java new file mode 100644 index 00000000000..aef8266ff23 --- /dev/null +++ b/src/com/android/launcher3/customization/ShadeShortcutFactory.java @@ -0,0 +1,45 @@ +package com.android.launcher3.customization; + +import android.content.Context; +import android.view.View; + +import com.android.launcher3.BaseDraggingActivity; +import com.android.launcher3.ItemInfo; +import com.android.launcher3.Launcher; +import com.android.launcher3.R; +import com.android.launcher3.popup.SystemShortcut; +import com.android.launcher3.popup.SystemShortcutFactory; + +@SuppressWarnings("unused") +public class ShadeShortcutFactory extends SystemShortcutFactory { + public ShadeShortcutFactory(Context context) { + super(new BottomSheetShortcut(), + new SystemShortcut.Widgets(), + new SystemShortcut.Install()); + } + + public static class BottomSheetShortcut extends SystemShortcut.AppInfo { + @Override + public View.OnClickListener getOnClickListener( + BaseDraggingActivity activity, ItemInfo itemInfo) { + Launcher launcher = (Launcher) activity; + final View.OnClickListener aiListener = super.getOnClickListener(launcher, itemInfo); + return new View.OnClickListener() { + private InfoBottomSheet cbs; + + @Override + public void onClick(View v) { + if (cbs == null) { + dismissTaskMenuView(launcher); + cbs = (InfoBottomSheet) launcher.getLayoutInflater().inflate( + R.layout.app_info_bottom_sheet, + launcher.getDragLayer(), + false); + cbs.setOnAppInfoClick(aiListener); + cbs.populateAndShow(itemInfo); + } + } + }; + } + } +} diff --git a/src/com/android/launcher3/dragndrop/DragView.java b/src/com/android/launcher3/dragndrop/DragView.java index f66d07e3d8e..074238d4cdd 100644 --- a/src/com/android/launcher3/dragndrop/DragView.java +++ b/src/com/android/launcher3/dragndrop/DragView.java @@ -109,6 +109,7 @@ public class DragView extends View implements LauncherStateManager.StateListener private Path mScaledMaskPath; private Drawable mBadge; private ColorMatrixColorFilter mBaseFilter; + private boolean mShowSpringIcon; /** * Construct the drag view. @@ -397,7 +398,7 @@ protected void onDraw(Canvas canvas) { } } - if (mScaledMaskPath != null) { + if (mScaledMaskPath != null && mShowSpringIcon) { int cnt = canvas.save(); canvas.clipPath(mScaledMaskPath); mBgSpringDrawable.draw(canvas); @@ -516,6 +517,9 @@ public void cancelAnimation() { public void move(int touchX, int touchY) { if (touchX > 0 && touchY > 0 && mLastTouchX > 0 && mLastTouchY > 0 && mScaledMaskPath != null) { + if (mLastTouchX != touchX || mLastTouchY != touchY) { + mShowSpringIcon = true; + } mTranslateX.animateToPos(mLastTouchX - touchX); mTranslateY.animateToPos(mLastTouchY - touchY); } diff --git a/src/com/android/launcher3/graphics/WorkspaceAndHotseatScrim.java b/src/com/android/launcher3/graphics/WorkspaceAndHotseatScrim.java index 15ff207bd1c..cdd31f86dbc 100644 --- a/src/com/android/launcher3/graphics/WorkspaceAndHotseatScrim.java +++ b/src/com/android/launcher3/graphics/WorkspaceAndHotseatScrim.java @@ -255,7 +255,7 @@ private void reapplySysUiAlpha() { } private void reapplySysUiAlphaNoInvalidate() { - float factor = mSysUiProgress * mSysUiAnimMultiplier; + float factor = 0.0f; mBottomMaskPaint.setAlpha(Math.round(MAX_HOTSEAT_SCRIM_ALPHA * factor)); if (mTopScrim != null) { mTopScrim.setAlpha(Math.round(255 * factor)); diff --git a/src/com/android/launcher3/notification/NotificationInfo.java b/src/com/android/launcher3/notification/NotificationInfo.java index e5525b2faa7..c70f7cae5ea 100644 --- a/src/com/android/launcher3/notification/NotificationInfo.java +++ b/src/com/android/launcher3/notification/NotificationInfo.java @@ -20,6 +20,8 @@ import android.app.Notification; import android.app.PendingIntent; import android.content.Context; +import android.content.pm.PackageManager; +import android.content.res.Resources; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.graphics.drawable.Icon; @@ -76,9 +78,13 @@ public NotificationInfo(Context context, StatusBarNotification statusBarNotifica mIconColor = statusBarNotification.getNotification().color; mIsIconLarge = false; } else { - // Use the large icon. - mIconDrawable = icon.loadDrawable(context); - mIsIconLarge = true; + try { + String pkg = statusBarNotification.getPackageName(); + Resources res = context.getPackageManager().getResourcesForApplication(pkg); + mIconDrawable = res.getDrawable(notification.icon); + } catch (PackageManager.NameNotFoundException | Resources.NotFoundException e) { + e.printStackTrace(); + } } if (mIconDrawable == null) { mIconDrawable = new BitmapDrawable(context.getResources(), LauncherAppState diff --git a/src/com/android/launcher3/popup/SystemShortcut.java b/src/com/android/launcher3/popup/SystemShortcut.java index cad73eb0309..c8f9eb734b9 100644 --- a/src/com/android/launcher3/popup/SystemShortcut.java +++ b/src/com/android/launcher3/popup/SystemShortcut.java @@ -6,6 +6,7 @@ import android.content.Intent; import android.graphics.Rect; import android.graphics.drawable.Icon; +import android.net.Uri; import android.os.Handler; import android.os.Looper; import android.view.View; @@ -229,6 +230,40 @@ public View.OnClickListener getOnClickListener(Launcher activity, ItemInfo itemI } } + public static class Uninstall extends SystemShortcut { + public Uninstall() { + super(R.drawable.ic_uninstall_no_shadow, R.string.uninstall_drop_target_label); + } + + @Override + public View.OnClickListener getOnClickListener( + BaseDraggingActivity activity, ItemInfo itemInfo) { + // Get application information. + String packageName = itemInfo.getTargetComponent().getPackageName(); + boolean isSystemApp = Utilities.isSystemApp(activity.getApplicationContext(), + packageName); + // Do not show the uninstall action if it's a system app. + if (isSystemApp) { + return null; + } + // Create uninstall action. + return createOnClickListener(activity, packageName); + } + + private View.OnClickListener createOnClickListener( + BaseDraggingActivity activity, String packageName) { + return view -> { + // Dismiss drop down. + dismissTaskMenuView(activity); + // Send intent to uninstall package. + Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE); + intent.setData(Uri.parse("package:" + packageName)); + intent.putExtra(Intent.EXTRA_RETURN_RESULT, true); + activity.startActivity(intent); + }; + } + } + protected static void dismissTaskMenuView(BaseDraggingActivity activity) { AbstractFloatingView.closeOpenViews(activity, true, AbstractFloatingView.TYPE_ALL & ~AbstractFloatingView.TYPE_REBIND_SAFE); diff --git a/src/com/android/launcher3/popup/SystemShortcutFactory.java b/src/com/android/launcher3/popup/SystemShortcutFactory.java index dfcc2f8224c..ce42ab6e9ba 100644 --- a/src/com/android/launcher3/popup/SystemShortcutFactory.java +++ b/src/com/android/launcher3/popup/SystemShortcutFactory.java @@ -41,6 +41,7 @@ public SystemShortcutFactory() { this(new SystemShortcut.AppInfo(), new SystemShortcut.Widgets(), new SystemShortcut.Install(), + new SystemShortcut.Uninstall(), new SystemShortcut.DismissPrediction()); } diff --git a/src/com/android/launcher3/touch/WorkspaceTouchListener.java b/src/com/android/launcher3/touch/WorkspaceTouchListener.java index 310d598b25c..7b250e7c842 100644 --- a/src/com/android/launcher3/touch/WorkspaceTouchListener.java +++ b/src/com/android/launcher3/touch/WorkspaceTouchListener.java @@ -23,8 +23,10 @@ import static com.android.launcher3.LauncherState.NORMAL; +import android.content.Context; import android.graphics.PointF; import android.graphics.Rect; +import android.os.PowerManager; import android.view.GestureDetector; import android.view.HapticFeedbackConstants; import android.view.MotionEvent; @@ -37,6 +39,7 @@ import com.android.launcher3.DeviceProfile; import com.android.launcher3.Launcher; import com.android.launcher3.Workspace; +import com.android.launcher3.Utilities; import com.android.launcher3.dragndrop.DragLayer; import com.android.launcher3.views.OptionsPopupView; import com.android.launcher3.userevent.nano.LauncherLogProto.Action; @@ -59,6 +62,8 @@ public class WorkspaceTouchListener extends GestureDetector.SimpleOnGestureListe private static final int STATE_PENDING_PARENT_INFORM = 2; private static final int STATE_COMPLETED = 3; + private static final String SLEEP_GESTURE = "pref_sleep_gesture"; + private final Rect mTempRect = new Rect(); private final Launcher mLauncher; private final Workspace mWorkspace; @@ -67,15 +72,21 @@ public class WorkspaceTouchListener extends GestureDetector.SimpleOnGestureListe private int mLongPressState = STATE_CANCELLED; + private final PowerManager mPm; + private final GestureDetector mGestureDetector; + private final Context mContext; + public WorkspaceTouchListener(Launcher launcher, Workspace workspace) { mLauncher = launcher; mWorkspace = workspace; + mContext = workspace.getContext(); // Use twice the touch slop as we are looking for long press which is more // likely to cause movement. mTouchSlop = 2 * ViewConfiguration.get(launcher).getScaledTouchSlop(); - mGestureDetector = new GestureDetector(workspace.getContext(), this); + mPm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); + mGestureDetector = new GestureDetector(mContext, this); } @Override @@ -181,4 +192,11 @@ public void onLongPress(MotionEvent event) { } } } + + @Override + public boolean onDoubleTap(MotionEvent event) { + if (Utilities.getPrefs(mContext).getBoolean(SLEEP_GESTURE, true)) + mPm.goToSleep(event.getEventTime()); + return true; + } } diff --git a/src/com/android/launcher3/util/PackageManagerHelper.java b/src/com/android/launcher3/util/PackageManagerHelper.java index 78d1d3ca8fe..1ca28f82dc7 100644 --- a/src/com/android/launcher3/util/PackageManagerHelper.java +++ b/src/com/android/launcher3/util/PackageManagerHelper.java @@ -112,6 +112,11 @@ public static boolean isAppSuspended(ApplicationInfo info) { * any permissions */ public boolean hasPermissionForActivity(Intent intent, String srcPackage) { + // b/270152142 + if (Intent.ACTION_CHOOSER.equals(intent.getAction())) { + // Chooser shortcuts is not a valid target + return false; + } ResolveInfo target = mPm.resolveActivity(intent, 0); if (target == null) { // Not a valid target