diff --git a/Android.mk b/Android.mk index 349a134d75..503f9aecb3 100644 --- a/Android.mk +++ b/Android.mk @@ -208,11 +208,13 @@ LOCAL_STATIC_ANDROID_LIBRARIES := Launcher3CommonDepsLib LOCAL_SRC_FILES := \ $(call all-java-files-under, src) \ $(call all-java-files-under, quickstep/src) \ - $(call all-java-files-under, go/src) + $(call all-java-files-under, go/src) \ + $(call all-java-files-under, go/quickstep/src) LOCAL_RESOURCE_DIR := \ $(LOCAL_PATH)/quickstep/res \ - $(LOCAL_PATH)/go/res + $(LOCAL_PATH)/go/res \ + $(LOCAL_PATH)/go/quickstep/res LOCAL_PROGUARD_FLAG_FILES := proguard.flags LOCAL_PROGUARD_ENABLED := full @@ -225,7 +227,7 @@ LOCAL_REQUIRED_MODULES := privapp_whitelist_com.android.launcher3 LOCAL_FULL_LIBS_MANIFEST_FILES := \ $(LOCAL_PATH)/go/AndroidManifest.xml \ - $(LOCAL_PATH)/quickstep/AndroidManifest-launcher.xml \ + $(LOCAL_PATH)/go/AndroidManifest-launcher.xml \ $(LOCAL_PATH)/AndroidManifest-common.xml LOCAL_MANIFEST_FILE := quickstep/AndroidManifest.xml diff --git a/go/AndroidManifest-launcher.xml b/go/AndroidManifest-launcher.xml new file mode 100644 index 0000000000..2223036a7a --- /dev/null +++ b/go/AndroidManifest-launcher.xml @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/go/quickstep/res/values/config.xml b/go/quickstep/res/values/config.xml new file mode 100644 index 0000000000..f3767748a5 --- /dev/null +++ b/go/quickstep/res/values/config.xml @@ -0,0 +1,18 @@ + + + + + \ No newline at end of file diff --git a/go/quickstep/res/values/strings.xml b/go/quickstep/res/values/strings.xml new file mode 100644 index 0000000000..fdd8397f36 --- /dev/null +++ b/go/quickstep/res/values/strings.xml @@ -0,0 +1,6 @@ + + + + + Share App + diff --git a/go/quickstep/src/com/android/launcher3/AppSharing.java b/go/quickstep/src/com/android/launcher3/AppSharing.java new file mode 100644 index 0000000000..b72e71c2b5 --- /dev/null +++ b/go/quickstep/src/com/android/launcher3/AppSharing.java @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.launcher3; + +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.net.Uri; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; + +import androidx.core.content.FileProvider; + +import com.android.launcher3.model.data.ItemInfo; +import com.android.launcher3.popup.SystemShortcut; + +import java.io.File; + +/** + * Defines the Share system shortcut and its factory. + * This shortcut can be added to the app long-press menu on the home screen. + * Clicking the button will initiate peer-to-peer sharing of the app. + */ +public final class AppSharing { + /** + * This flag enables this feature. It is defined here rather than in launcher3's FeatureFlags + * because it is unique to Go and not toggleable at runtime. + */ + public static final boolean ENABLE_APP_SHARING = true; + + private static final String TAG = "AppSharing"; + private static final String FILE_PROVIDER_SUFFIX = ".overview.fileprovider"; + private static final String APP_EXSTENSION = ".apk"; + private static final String APP_MIME_TYPE = "application/application"; + + private final String mSharingComponent; + + private AppSharing(Launcher launcher) { + mSharingComponent = launcher.getText(R.string.app_sharing_component).toString(); + } + + private boolean canShare(ItemInfo info) { + /** + * TODO: Implement once b/168831749 has been resolved + * The implementation should check the validity of the app. + * It should also check whether the app is free or paid, returning false in the latter case. + * For now, all checks occur in the sharing app. + * So, we simply check whether the sharing app is defined. + */ + return !TextUtils.isEmpty(mSharingComponent); + } + + private Uri getShareableUri(Context context, String path, String displayName) { + String authority = BuildConfig.APPLICATION_ID + FILE_PROVIDER_SUFFIX; + File pathFile = new File(path); + return FileProvider.getUriForFile(context, authority, pathFile, displayName); + } + + private SystemShortcut getShortcut(Launcher launcher, ItemInfo info) { + if (!canShare(info)) { + return null; + } + + return new Share(launcher, info); + } + + /** + * The Share App system shortcut, used to initiate p2p sharing of a given app + */ + public final class Share extends SystemShortcut { + public Share(Launcher target, ItemInfo itemInfo) { + super(R.drawable.ic_share, R.string.app_share_drop_target_label, target, itemInfo); + } + + @Override + public void onClick(View view) { + Intent sendIntent = new Intent(); + sendIntent.setAction(Intent.ACTION_SEND); + + ComponentName targetComponent = mItemInfo.getTargetComponent(); + if (targetComponent == null) { + Log.e(TAG, "Item missing target component"); + return; + } + String packageName = targetComponent.getPackageName(); + PackageManager packageManager = view.getContext().getPackageManager(); + String sourceDir, appLabel; + try { + PackageInfo packageInfo = packageManager.getPackageInfo(packageName, 0); + sourceDir = packageInfo.applicationInfo.sourceDir; + appLabel = packageManager.getApplicationLabel(packageInfo.applicationInfo) + .toString() + APP_EXSTENSION; + } catch (Exception e) { + Log.e(TAG, "Could not find info for package \"" + packageName + "\""); + return; + } + Uri uri = getShareableUri(view.getContext(), sourceDir, appLabel); + sendIntent.putExtra(Intent.EXTRA_STREAM, uri); + sendIntent.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName); + + sendIntent.setType(APP_MIME_TYPE); + sendIntent.setComponent(ComponentName.unflattenFromString(mSharingComponent)); + + mTarget.startActivitySafely(view, sendIntent, mItemInfo); + + AbstractFloatingView.closeAllOpenViews(mTarget); + } + } + + /** + * Shortcut factory for generating the Share App button + */ + public static final SystemShortcut.Factory SHORTCUT_FACTORY = (launcher, itemInfo) -> + (new AppSharing(launcher)).getShortcut(launcher, itemInfo); +} diff --git a/go/quickstep/src/com/android/launcher3/Launcher3QuickStepGo.java b/go/quickstep/src/com/android/launcher3/Launcher3QuickStepGo.java new file mode 100644 index 0000000000..8bd0fec2de --- /dev/null +++ b/go/quickstep/src/com/android/launcher3/Launcher3QuickStepGo.java @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.launcher3; + +import com.android.launcher3.popup.SystemShortcut; +import com.android.launcher3.uioverrides.QuickstepLauncher; + +import java.util.stream.Stream; + +/** + * The Launcher variant used for Android Go Edition + */ +public class Launcher3QuickStepGo extends QuickstepLauncher { + private static final String TAG = "Launcher3QuickStepGo"; + + @Override + public Stream getSupportedShortcuts() { + Stream shortcuts = super.getSupportedShortcuts(); + + if (AppSharing.ENABLE_APP_SHARING) { + shortcuts = Stream.concat(shortcuts, Stream.of(AppSharing.SHORTCUT_FACTORY)); + } + + return shortcuts; + } +} diff --git a/quickstep/res/xml/overview_file_provider_paths.xml b/quickstep/res/xml/overview_file_provider_paths.xml index 14d74596e7..07e323609f 100644 --- a/quickstep/res/xml/overview_file_provider_paths.xml +++ b/quickstep/res/xml/overview_file_provider_paths.xml @@ -2,4 +2,5 @@ + \ No newline at end of file