Merge "Add shortcut to install an app to Private space" into main

This commit is contained in:
Anna Zhuravleva
2024-01-12 15:51:05 +00:00
committed by Android (Google) Code Review
9 changed files with 134 additions and 2 deletions

View File

@@ -97,3 +97,10 @@ flag {
description: "Enables support for archived apps in Launcher3, such as empty progress bar etc."
bug: "210590852"
}
flag {
name: "enable_private_space_install_shortcut"
namespace: "launcher"
description: "Enables long-press shortcut to install a copy of an app to Private space"
bug: "316118005"
}

View File

@@ -129,8 +129,10 @@ public class ApiWrapper {
public static Intent getAppMarketActivityIntent(Context context, String packageName,
UserHandle user) {
LauncherApps launcherApps = context.getSystemService(LauncherApps.class);
if (android.os.Flags.allowPrivateProfile() && Flags.enablePrivateSpace()
&& Flags.privateSpaceAppInstallerButton()) {
if (android.os.Flags.allowPrivateProfile()
&& Flags.enablePrivateSpace()
&& (Flags.privateSpaceAppInstallerButton()
|| Flags.enablePrivateSpaceInstallShortcut())) {
StartActivityParams params = new StartActivityParams((PendingIntent) null, 0);
params.intentSender = launcherApps.getAppMarketActivityIntent(packageName, user);
return ProxyActivityStarter.getLaunchIntent(context, params);

View File

@@ -40,6 +40,7 @@ import static com.android.launcher3.model.data.ItemInfo.NO_MATCHING_ID;
import static com.android.launcher3.popup.QuickstepSystemShortcut.getSplitSelectShortcutByPosition;
import static com.android.launcher3.popup.SystemShortcut.APP_INFO;
import static com.android.launcher3.popup.SystemShortcut.INSTALL;
import static com.android.launcher3.popup.SystemShortcut.PRIVATE_PROFILE_INSTALL;
import static com.android.launcher3.popup.SystemShortcut.WIDGETS;
import static com.android.launcher3.taskbar.LauncherTaskbarUIController.ALL_APPS_PAGE_PROGRESS_INDEX;
import static com.android.launcher3.taskbar.LauncherTaskbarUIController.MINUS_ONE_PAGE_PROGRESS_INDEX;
@@ -95,6 +96,7 @@ import androidx.annotation.RequiresApi;
import com.android.app.viewcapture.SettingsAwareViewCapture;
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Flags;
import com.android.launcher3.HomeTransitionController;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherSettings.Favorites;
@@ -415,6 +417,10 @@ public class QuickstepLauncher extends Launcher {
shortcuts.addAll(getSplitShortcuts());
shortcuts.add(WIDGETS);
shortcuts.add(INSTALL);
if (Flags.enablePrivateSpaceInstallShortcut()) {
shortcuts.add(PRIVATE_PROFILE_INSTALL);
}
return shortcuts.stream();
}

View File

@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2024 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M420,600L540,600L517,471Q537,461 548.5,442Q560,423 560,400Q560,367 536.5,343.5Q513,320 480,320Q447,320 423.5,343.5Q400,367 400,400Q400,423 411.5,442Q423,461 443,471L420,600ZM480,880Q341,845 250.5,720.5Q160,596 160,444L160,200L480,80L800,200L800,444Q800,596 709.5,720.5Q619,845 480,880ZM480,796Q584,763 652,664Q720,565 720,444L720,255L480,165L240,255L240,444Q240,565 308,664Q376,763 480,796ZM480,480Q480,480 480,480Q480,480 480,480L480,480L480,480L480,480L480,480Q480,480 480,480Q480,480 480,480Z"/>
</vector>

View File

@@ -171,6 +171,8 @@
<string name="uninstall_drop_target_label">Uninstall</string>
<!-- Label for app info drop target. [CHAR_LIMIT=20] -->
<string name="app_info_drop_target_label">App info</string>
<!-- Label for install to private profile shortcut label. [CHAR_LIMIT=20] -->
<string name="install_private_system_shortcut_label">Install in private</string>
<!-- Label for install drop target. [CHAR_LIMIT=20] -->
<string name="install_drop_target_label">Install</string>
<!-- Label for install dismiss prediction. -->

View File

@@ -1315,6 +1315,10 @@ public class ActivityAllAppsContainerView<T extends Context & ActivityContext>
: mViewPager == null ? AdapterHolder.MAIN : mViewPager.getNextPage();
}
public PrivateProfileManager getPrivateProfileManager() {
return mPrivateProfileManager;
}
/**
* Adds an update listener to animator that adds springs to the animation.
*/

View File

@@ -94,6 +94,19 @@ public abstract class UserProfileManager {
return mCurrentState;
}
/** Returns if user profile is enabled. */
public boolean isEnabled() {
return mCurrentState == STATE_ENABLED;
}
/** Returns the UserHandle corresponding to the profile type, null in case no matches found. */
public UserHandle getProfileUser() {
return mUserCache.getUserProfiles().stream()
.filter(getUserMatcher())
.findAny()
.orElse(null);
}
/** Logs Event to StatsLogManager. */
protected void logEvents(StatsLogManager.EventEnum event) {
mStatsLogManager.logger().log(event);

View File

@@ -701,6 +701,9 @@ public class StatsLogManager implements ResourceBasedOverride {
@UiEvent(doc = "User tapped private space settings button")
LAUNCHER_PRIVATE_SPACE_SETTINGS_TAP(1550),
@UiEvent(doc = "User tapped on install to private space system shortcut.")
LAUNCHER_PRIVATE_SPACE_INSTALL_SYSTEM_SHORTCUT_TAP(1565),
// ADD MORE
;

View File

@@ -1,5 +1,6 @@
package com.android.launcher3.popup;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_PRIVATE_SPACE_INSTALL_SYSTEM_SHORTCUT_TAP;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_SYSTEM_SHORTCUT_APP_INFO_TAP;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_SYSTEM_SHORTCUT_WIDGETS_TAP;
@@ -8,6 +9,7 @@ import android.content.Context;
import android.content.Intent;
import android.graphics.Rect;
import android.os.Process;
import android.os.UserHandle;
import android.view.View;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.ImageView;
@@ -20,10 +22,12 @@ import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.Launcher;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.allapps.PrivateProfileManager;
import com.android.launcher3.model.WidgetItem;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.uioverrides.ApiWrapper;
import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.InstantAppResolver;
import com.android.launcher3.util.PackageManagerHelper;
import com.android.launcher3.util.PackageUserKey;
@@ -212,6 +216,69 @@ public abstract class SystemShortcut<T extends Context & ActivityContext> extend
}
}
public static final Factory<Launcher> PRIVATE_PROFILE_INSTALL =
(launcher, itemInfo, originalView) -> {
if (itemInfo.getTargetComponent() == null
|| !(itemInfo instanceof com.android.launcher3.model.data.AppInfo)
|| !itemInfo.getContainerInfo().hasAllAppsContainer()
|| !Process.myUserHandle().equals(itemInfo.user)) {
return null;
}
PrivateProfileManager privateProfileManager =
launcher.getAppsView().getPrivateProfileManager();
if (privateProfileManager == null || !privateProfileManager.isEnabled()) {
return null;
}
UserHandle privateProfileUser = privateProfileManager.getProfileUser();
if (privateProfileUser == null) {
return null;
}
// Do not show shortcut if an app is already installed to the space
ComponentKey targetKey =
new ComponentKey(itemInfo.getTargetComponent(), privateProfileUser);
if (launcher.getAppsView().getAppsStore().getApp(targetKey) != null) {
return null;
}
// TODO(b/302666597): do not install app if it's in deny list (e.g. settings)
return new InstallToPrivateProfile(
launcher, itemInfo, originalView, privateProfileUser);
};
static class InstallToPrivateProfile extends SystemShortcut<Launcher> {
UserHandle mSpaceUser;
InstallToPrivateProfile(
Launcher target, ItemInfo itemInfo, View originalView, UserHandle spaceUser) {
// TODO(b/302666597): update icon once available
super(
R.drawable.ic_install_to_private,
R.string.install_private_system_shortcut_label,
target,
itemInfo,
originalView);
mSpaceUser = spaceUser;
}
@Override
public void onClick(View view) {
Intent intent =
ApiWrapper.getAppMarketActivityIntent(
view.getContext(),
mItemInfo.getTargetComponent().getPackageName(),
mSpaceUser);
mTarget.startActivitySafely(view, intent, mItemInfo);
AbstractFloatingView.closeAllOpenViews(mTarget);
mTarget.getStatsLogManager()
.logger()
.withItemInfo(mItemInfo)
.log(LAUNCHER_PRIVATE_SPACE_INSTALL_SYSTEM_SHORTCUT_TAP);
}
}
public static final Factory<BaseDraggingActivity> INSTALL =
(activity, itemInfo, originalView) -> {
boolean supportsWebUI = (itemInfo instanceof WorkspaceItemInfo)