diff options
Diffstat (limited to 'src/com/android/launcher3/discovery')
5 files changed, 365 insertions, 0 deletions
diff --git a/src/com/android/launcher3/discovery/AppDiscoveryAppInfo.java b/src/com/android/launcher3/discovery/AppDiscoveryAppInfo.java new file mode 100644 index 000000000..50e979aac --- /dev/null +++ b/src/com/android/launcher3/discovery/AppDiscoveryAppInfo.java @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2017 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.discovery; + +import android.content.ComponentName; +import android.content.Intent; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.drawable.Drawable; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; + +import com.android.launcher3.AppInfo; +import com.android.launcher3.Launcher; +import com.android.launcher3.LauncherSettings; +import com.android.launcher3.R; +import com.android.launcher3.ShortcutInfo; + +public class AppDiscoveryAppInfo extends AppInfo { + + private final @NonNull Launcher mLauncher; + + public final boolean showAsDiscoveryItem; + public final boolean isInstantApp; + public final float rating; + public final long reviewCount; + public final @NonNull String publisher; + public final @NonNull Intent installIntent; + public final @NonNull Intent launchIntent; + public final @Nullable String priceFormatted; + + public AppDiscoveryAppInfo(AppDiscoveryItem item, Launcher launcher) { + this.mLauncher = launcher; + this.intent = item.isInstantApp ? item.launchIntent : item.installIntent; + this.title = item.title; + this.iconBitmap = item.bitmap; + this.isDisabled = ShortcutInfo.DEFAULT; + this.usingLowResIcon = false; + this.isInstantApp = item.isInstantApp; + this.rating = item.starRating; + this.showAsDiscoveryItem = true; + this.publisher = item.publisher != null ? item.publisher : ""; + this.priceFormatted = item.price; + this.componentName = new ComponentName(item.packageName, ""); + this.installIntent = item.installIntent; + this.launchIntent = item.launchIntent; + this.reviewCount = item.reviewCount; + this.itemType = LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT; + } + + @Override + public ShortcutInfo makeShortcut() { + if (!isDragAndDropSupported()) { + throw new RuntimeException("DnD is currently not supported for discovered store apps"); + } + ShortcutInfo shortcutInfo = super.makeShortcut(); + if (isInstantApp) { + int iconSize = iconBitmap.getWidth(); + int badgeSize = mLauncher.getResources().getDimensionPixelOffset(R.dimen.badge_size); + Bitmap icon = Bitmap.createBitmap(iconBitmap); + Drawable badgeDrawable = mLauncher.getDrawable(R.drawable.ic_instant_app); + badgeDrawable.setBounds(iconSize - badgeSize, iconSize - badgeSize, iconSize, iconSize); + Canvas canvas = new Canvas(icon); + badgeDrawable.draw(canvas); + shortcutInfo.iconBitmap = icon; + } + return shortcutInfo; + } + + public boolean isDragAndDropSupported() { + return isInstantApp; + } + +} diff --git a/src/com/android/launcher3/discovery/AppDiscoveryItem.java b/src/com/android/launcher3/discovery/AppDiscoveryItem.java new file mode 100644 index 000000000..7c10371d0 --- /dev/null +++ b/src/com/android/launcher3/discovery/AppDiscoveryItem.java @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2017 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.discovery; + +import android.content.Context; +import android.content.Intent; +import android.graphics.Bitmap; + +/** + * This class represents the model for a discovered app via app discovery. + * It holds all information for one result retrieved from an app discovery service. + */ +public class AppDiscoveryItem { + + public final String packageName; + public final boolean isInstantApp; + public final float starRating; + public final long reviewCount; + public final Intent launchIntent; + public final Intent installIntent; + public final CharSequence title; + public final String publisher; + public final String price; + public final Bitmap bitmap; + + public AppDiscoveryItem(String packageName, + boolean isInstantApp, + float starRating, + long reviewCount, + CharSequence title, + String publisher, + Bitmap bitmap, + String price, + Intent launchIntent, + Intent installIntent) { + this.packageName = packageName; + this.isInstantApp = isInstantApp; + this.starRating = starRating; + this.reviewCount = reviewCount; + this.launchIntent = launchIntent; + this.installIntent = installIntent; + this.title = title; + this.publisher = publisher; + this.price = price; + this.bitmap = bitmap; + } + +} diff --git a/src/com/android/launcher3/discovery/AppDiscoveryItemView.java b/src/com/android/launcher3/discovery/AppDiscoveryItemView.java new file mode 100644 index 000000000..6faad87ab --- /dev/null +++ b/src/com/android/launcher3/discovery/AppDiscoveryItemView.java @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2017 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.discovery; + +import android.content.Context; +import android.support.annotation.NonNull; +import android.util.AttributeSet; +import android.view.View; +import android.widget.ImageView; +import android.widget.RelativeLayout; +import android.widget.TextView; + +import com.android.launcher3.R; + +import java.text.DecimalFormat; +import java.text.NumberFormat; + +public class AppDiscoveryItemView extends RelativeLayout { + + private static boolean SHOW_REVIEW_COUNT = false; + + private ImageView mImage; + private ImageView mBadge; + private TextView mTitle; + private TextView mRatingText; + private RatingView mRatingView; + private TextView mReviewCount; + private TextView mPrice; + private OnLongClickListener mOnLongClickListener; + + public AppDiscoveryItemView(Context context) { + this(context, null); + } + + public AppDiscoveryItemView(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public AppDiscoveryItemView(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + } + + @Override + protected void onFinishInflate() { + super.onFinishInflate(); + this.mImage = (ImageView) findViewById(R.id.image); + this.mBadge = (ImageView) findViewById(R.id.badge); + this.mTitle = (TextView) findViewById(R.id.title); + this.mRatingText = (TextView) findViewById(R.id.rating); + this.mRatingView = (RatingView) findViewById(R.id.rating_view); + this.mPrice = (TextView) findViewById(R.id.price); + this.mReviewCount = (TextView) findViewById(R.id.review_count); + } + + public void init(OnClickListener clickListener, + AccessibilityDelegate accessibilityDelegate, + OnLongClickListener onLongClickListener) { + setOnClickListener(clickListener); + mImage.setOnClickListener(clickListener); + setAccessibilityDelegate(accessibilityDelegate); + mOnLongClickListener = onLongClickListener; + } + + public void apply(@NonNull AppDiscoveryAppInfo info) { + setTag(info); + mImage.setTag(info); + mImage.setImageBitmap(info.iconBitmap); + mImage.setOnLongClickListener(info.isDragAndDropSupported() ? mOnLongClickListener : null); + mBadge.setVisibility(info.isInstantApp ? View.VISIBLE : View.GONE); + mTitle.setText(info.title); + mPrice.setText(info.priceFormatted != null ? info.priceFormatted : ""); + mReviewCount.setVisibility(SHOW_REVIEW_COUNT ? View.VISIBLE : View.GONE); + if (info.rating >= 0) { + mRatingText.setText(new DecimalFormat("#.#").format(info.rating)); + mRatingView.setRating(info.rating); + mRatingView.setVisibility(View.VISIBLE); + String reviewCountFormatted = NumberFormat.getInstance().format(info.reviewCount); + mReviewCount.setText("(" + reviewCountFormatted + ")"); + } else { + // if we don't have a rating + mRatingView.setVisibility(View.GONE); + mRatingText.setText(""); + mReviewCount.setText(""); + } + } +} diff --git a/src/com/android/launcher3/discovery/AppDiscoveryUpdateState.java b/src/com/android/launcher3/discovery/AppDiscoveryUpdateState.java new file mode 100644 index 000000000..0700a1023 --- /dev/null +++ b/src/com/android/launcher3/discovery/AppDiscoveryUpdateState.java @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2017 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.discovery; + +public enum AppDiscoveryUpdateState { + START, UPDATE, END +} diff --git a/src/com/android/launcher3/discovery/RatingView.java b/src/com/android/launcher3/discovery/RatingView.java new file mode 100644 index 000000000..8fe63d6ba --- /dev/null +++ b/src/com/android/launcher3/discovery/RatingView.java @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2017 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.discovery; + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.drawable.ClipDrawable; +import android.graphics.drawable.Drawable; +import android.util.AttributeSet; +import android.view.Gravity; +import android.view.View; + +import com.android.launcher3.R; + +/** + * A simple rating view that shows stars with a rating from 0-5. + */ +public class RatingView extends View { + + private static final float WIDTH_FACTOR = 0.9f; + private static final int MAX_LEVEL = 10000; + private static final int MAX_STARS = 5; + + private final Drawable mStarDrawable; + private final int mColorGray; + private final int mColorHighlight; + + private float rating; + + public RatingView(Context context) { + this(context, null); + } + + public RatingView(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public RatingView(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + mStarDrawable = getResources().getDrawable(R.drawable.ic_star_rating, null); + mColorGray = 0x1E000000; + mColorHighlight = 0x8A000000; + } + + public void setRating(float rating) { + this.rating = Math.min(Math.max(rating, 0), MAX_STARS); + } + + @Override + protected void onDraw(Canvas canvas) { + drawStars(canvas, MAX_STARS, mColorGray); + drawStars(canvas, rating, mColorHighlight); + } + + private void drawStars(Canvas canvas, float stars, int color) { + int fullWidth = getLayoutParams().width; + int cellWidth = fullWidth / MAX_STARS; + int starWidth = (int) (cellWidth * WIDTH_FACTOR); + int padding = cellWidth - starWidth; + int fullStars = (int) stars; + float partialStarFactor = stars - fullStars; + + for (int i = 0; i < fullStars; i++) { + int x = i * cellWidth + padding; + Drawable star = mStarDrawable.getConstantState().newDrawable().mutate(); + star.setTint(color); + star.setBounds(x, padding, x + starWidth, padding + starWidth); + star.draw(canvas); + } + if (partialStarFactor > 0f) { + int x = fullStars * cellWidth + padding; + ClipDrawable star = new ClipDrawable(mStarDrawable, + Gravity.LEFT, ClipDrawable.HORIZONTAL); + star.setTint(color); + star.setLevel((int) (MAX_LEVEL * partialStarFactor)); + star.setBounds(x, padding, x + starWidth, padding + starWidth); + star.draw(canvas); + } + } +} |