/* ******************************************************************************** * Copyright (c) 2012 Samsung Electronics, Inc. * All rights reserved. * * This software is a confidential and proprietary information of Samsung * Electronics, Inc. ("Confidential Information"). You shall not disclose such * Confidential Information and shall use it only in accordance with the terms * of the license agreement you entered into with Samsung Electronics. ******************************************************************************** */ package com.sprc.circlelauncher; import java.util.ArrayList; import java.util.Collections; import java.util.List; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.Adapter; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.ListView; import android.widget.TextView; import com.sprc.circlelauncher.SPen.Input; import com.sprc.circlelauncher.SPen.InputHandleListener; import com.sprc.circlelauncher.view.CircleListView; /** * A {@link BaseAdapter} implementation that provides a list of applications. * * @author sprc * */ public class PackageAdapter extends BaseAdapter implements InputHandleListener { private final Context mContext; private List<ResolveInfo> mApplications; private final LayoutInflater mInflater; private final PackageManager mPackageManager; private OnCircleItemClickListener mOnCircleItemClickListener; private OnCircleItemLongClickListener mOnCircleItemLongClickListener; private OnCircleItemHoverListener mOnCircleItemHoverListener; private OnCircleItemHoverButtonListener mOnCircleItemHoverButtonListener; private final SPen mSpen; public PackageAdapter(final Context ctx) { mContext = ctx; mInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); mPackageManager = mContext.getPackageManager(); mSpen = new SPen(ctx); mApplications = new ArrayList<ResolveInfo>(); } /** * Reloads the application list and calls {@link #notifyDataSetChanged()} on this {@link Adapter}. */ public void reloadApplications() { final Intent intent = new Intent(Intent.ACTION_MAIN); intent.addCategory(Intent.CATEGORY_LAUNCHER); mApplications = mPackageManager.queryIntentActivities(intent, PackageManager.GET_META_DATA); ArrayList<ResolveInfo> blackListedApplications = new ArrayList<ResolveInfo>(); final SharedPreferences prefs = mContext.getSharedPreferences(ChooseAppsActivity.class.getSimpleName(), Context.MODE_PRIVATE); for (ResolveInfo info : mApplications) { if (!prefs.getBoolean(info.activityInfo.name, true)) { // Remove this app from the list only if it's corresponding key in SharedPreferences is false blackListedApplications.add(info); } } mApplications.removeAll(blackListedApplications); Collections.sort(mApplications, new ResolveInfo.DisplayNameComparator(mPackageManager)); notifyDataSetChanged(); } /** * Since we want to loop our list we return {@link Integer#MAX_VALUE}. * * {@inheritDoc} */ public int getCount() { return Integer.MAX_VALUE; } /** * Retrieves an item in a position from the range (0; {@link Integer#MAX_VALUE}). * * {@inheritDoc} */ public Object getItem(final int position) { if (mApplications.size() > 0) { return mApplications.get(position % mApplications.size()); } return null; } public long getItemId(final int position) { final ResolveInfo info = ((ResolveInfo) getItem(position)); if (info == null) { return 0l; } else { return info.activityInfo.applicationInfo.uid; } } public View getView(final int position, final View convertView, final ViewGroup parent) { ViewHolder holder; View v = convertView; if (v == null) { v = mInflater.inflate(R.layout.circle_list_item, null); mSpen.registerInputHandler(v, this); holder = new ViewHolder(); holder.mIcon = (ImageView) v.findViewById(R.id.icon); holder.mAppName = (TextView) v.findViewById(R.id.label_app_name); v.setTag(holder); } else { holder = (ViewHolder) v.getTag(); } // We use those tags to have the access to parent and position in listeners. v.setTag(R.id.key_parent, parent); v.setTag(R.id.key_position, position); final ResolveInfo resolveInfo = (ResolveInfo) getItem(position); if (resolveInfo != null) { holder.mIcon.setImageDrawable(resolveInfo.loadIcon(mPackageManager)); holder.mAppName.setText(resolveInfo.loadLabel(mPackageManager)); } else { holder.mIcon.setImageDrawable(null); holder.mAppName.setText(null); } return v; } public void setOnCircleItemClickListener(final OnCircleItemClickListener listener) { mOnCircleItemClickListener = listener; } public void setOnCircleItemLongClickListener(final OnCircleItemLongClickListener listener) { mOnCircleItemLongClickListener = listener; } public void setOnCircleItemHoverListener(final OnCircleItemHoverListener listener) { mOnCircleItemHoverListener = listener; } public void setOnCircleItemHoverButtonUpListener(final OnCircleItemHoverButtonListener listener) { mOnCircleItemHoverButtonListener = listener; } public void setOnCircleItemHoverButtonDownListener(final OnCircleItemHoverButtonListener listener) { mOnCircleItemHoverButtonListener = listener; } private class ViewHolder { ImageView mIcon; TextView mAppName; } /** * Handles click events coming from {@link CircleListView} elements. * * It is not possible to move the clickable region of each {@link ListView} item. The workaround involved setting * {@link OnClickListener} on each list element in the {@link BaseAdapter} implementation. */ public interface OnCircleItemClickListener { void onClick(View v, BaseAdapter adapter); } public interface OnCircleItemLongClickListener { boolean onLongClick(View v, BaseAdapter adapter); } public interface OnCircleItemHoverListener { boolean onHover(View v, BaseAdapter adapter, long eventTime); } public interface OnCircleItemHoverButtonListener { boolean onHoverButtonUp(View v, BaseAdapter adapter, long eventTime); boolean onHoverButtonDown(View v, BaseAdapter adapter, long eventTime); } public void handleEvent(Input input) { switch (input.getInputType()) { case CLICK: if (SPen.ClickAction.CLICK.equals(input.getClickAction())) { if (mOnCircleItemClickListener != null) { mOnCircleItemClickListener.onClick(input.getView(), PackageAdapter.this); } } else if (SPen.ClickAction.LONGCLICK.equals(input.getClickAction())) { if (mOnCircleItemLongClickListener != null) { mOnCircleItemLongClickListener.onLongClick(input.getView(), PackageAdapter.this); } } break; case ERASER: break; case FINGER: break; case HOVER: if (SPen.InputAction.MOVE.equals(input.getInputAction())) { if (mOnCircleItemHoverListener != null) { mOnCircleItemHoverListener.onHover(input.getView(), PackageAdapter.this, input.getEventTime()); } } else if (SPen.ButtonAction.UP.equals(input.getButtonAction())) { if (mOnCircleItemHoverButtonListener != null) { mOnCircleItemHoverButtonListener.onHoverButtonUp(input.getView(), PackageAdapter.this, input.getEventTime()); } } else if (SPen.ButtonAction.DOWN.equals(input.getButtonAction())) { if (mOnCircleItemHoverButtonListener != null) { mOnCircleItemHoverButtonListener.onHoverButtonDown(input.getView(), PackageAdapter.this, input.getEventTime()); } } break; case PEN: break; case UNDEFINED: break; default: break; } } }