diff options
Diffstat (limited to 'InCallUI/src/com/android/incallui/InCallContactInteractions.java')
-rw-r--r-- | InCallUI/src/com/android/incallui/InCallContactInteractions.java | 399 |
1 files changed, 0 insertions, 399 deletions
diff --git a/InCallUI/src/com/android/incallui/InCallContactInteractions.java b/InCallUI/src/com/android/incallui/InCallContactInteractions.java deleted file mode 100644 index 88070fe37..000000000 --- a/InCallUI/src/com/android/incallui/InCallContactInteractions.java +++ /dev/null @@ -1,399 +0,0 @@ -/* - * Copyright (C) 2015 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.incallui; - -import com.google.common.annotations.VisibleForTesting; - -import android.content.Context; -import android.location.Address; -import android.text.TextUtils; -import android.text.format.DateFormat; -import android.util.Pair; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ArrayAdapter; -import android.widget.ImageView; -import android.widget.ListAdapter; -import android.widget.RelativeLayout; -import android.widget.RelativeLayout.LayoutParams; -import android.widget.TextView; - -import com.android.dialer.R; - -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Date; -import java.util.List; -import java.util.Locale; - -/** - * Wrapper class for objects that are used in generating the context about the contact in the InCall - * screen. - * - * This handles generating the appropriate resource for the ListAdapter based on whether the contact - * is a business contact or not and logic for the manipulation of data for the call context. - */ -public class InCallContactInteractions { - private static final String TAG = InCallContactInteractions.class.getSimpleName(); - - private Context mContext; - private InCallContactInteractionsListAdapter mListAdapter; - private boolean mIsBusiness; - private View mBusinessHeaderView; - private LayoutInflater mInflater; - - public InCallContactInteractions(Context context, boolean isBusiness) { - mContext = context; - mInflater = (LayoutInflater) - context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); - switchContactType(isBusiness); - } - - public InCallContactInteractionsListAdapter getListAdapter() { - return mListAdapter; - } - - /** - * Switches the "isBusiness" value, if applicable. Recreates the list adapter with the resource - * corresponding to the new isBusiness value if the "isBusiness" value is switched. - * - * @param isBusiness Whether or not the contact is a business. - * - * @return {@code true} if a new list adapter was created, {@code} otherwise. - */ - public boolean switchContactType(boolean isBusiness) { - if (mIsBusiness != isBusiness || mListAdapter == null) { - mIsBusiness = isBusiness; - mListAdapter = new InCallContactInteractionsListAdapter(mContext, - mIsBusiness ? R.layout.business_context_info_list_item - : R.layout.person_context_info_list_item); - return true; - } - return false; - } - - public View getBusinessListHeaderView() { - if (mBusinessHeaderView == null) { - mBusinessHeaderView = mInflater.inflate( - R.layout.business_contact_context_list_header, null); - } - return mBusinessHeaderView; - } - - public void setBusinessInfo(Address address, float distance, - List<Pair<Calendar, Calendar>> openingHours) { - mListAdapter.clear(); - List<ContactContextInfo> info = new ArrayList<ContactContextInfo>(); - - // Hours of operation - if (openingHours != null) { - BusinessContextInfo hoursInfo = constructHoursInfo(openingHours); - if (hoursInfo != null) { - info.add(hoursInfo); - } - } - - // Location information - if (address != null) { - BusinessContextInfo locationInfo = constructLocationInfo(address, distance); - info.add(locationInfo); - } - - mListAdapter.addAll(info); - } - - /** - * Construct a BusinessContextInfo object containing hours of operation information. - * The format is: - * [Open now/Closed now] - * [Hours] - * - * @param openingHours - * @return BusinessContextInfo object with the schedule icon, the heading set to whether the - * business is open or not and the details set to the hours of operation. - */ - private BusinessContextInfo constructHoursInfo(List<Pair<Calendar, Calendar>> openingHours) { - try { - return constructHoursInfo(Calendar.getInstance(), openingHours); - } catch (Exception e) { - // Catch all exceptions here because we don't want any crashes if something goes wrong. - Log.e(TAG, "Error constructing hours info: ", e); - } - return null; - } - - /** - * Pass in arbitrary current calendar time. - */ - @VisibleForTesting - BusinessContextInfo constructHoursInfo(Calendar currentTime, - List<Pair<Calendar, Calendar>> openingHours) { - if (currentTime == null || openingHours == null || openingHours.size() == 0) { - return null; - } - - BusinessContextInfo hoursInfo = new BusinessContextInfo(); - hoursInfo.iconId = R.drawable.ic_schedule_white_24dp; - - boolean isOpenNow = false; - // This variable records which interval the current time is after. 0 denotes none of the - // intervals, 1 after the first interval, etc. It is also the index of the interval the - // current time is in (if open) or the next interval (if closed). - int afterInterval = 0; - // This variable counts the number of time intervals in today's opening hours. - int todaysIntervalCount = 0; - - for (Pair<Calendar, Calendar> hours : openingHours) { - if (hours.first.compareTo(currentTime) <= 0 - && currentTime.compareTo(hours.second) < 0) { - // If the current time is on or after the opening time and strictly before the - // closing time, then this business is open. - isOpenNow = true; - } - - if (currentTime.get(Calendar.DAY_OF_YEAR) == hours.first.get(Calendar.DAY_OF_YEAR)) { - todaysIntervalCount += 1; - } - - if (currentTime.compareTo(hours.second) > 0) { - // This assumes that the list of intervals is sorted by time. - afterInterval += 1; - } - } - - hoursInfo.heading = isOpenNow ? mContext.getString(R.string.open_now) - : mContext.getString(R.string.closed_now); - - /* - * The following logic determines what to display in various cases for hours of operation. - * - * - Display all intervals if open now and number of intervals is <=2. - * - Display next closing time if open now and number of intervals is >2. - * - Display next opening time if currently closed but opens later today. - * - Display last time it closed today if closed now and tomorrow's hours are unknown. - * - Display tomorrow's first open time if closed today and tomorrow's hours are known. - * - * NOTE: The logic below assumes that the intervals are sorted by ascending time. Possible - * TODO to modify the logic above and ensure this is true. - */ - if (isOpenNow) { - if (todaysIntervalCount == 1) { - hoursInfo.detail = getTimeSpanStringForHours(openingHours.get(0)); - } else if (todaysIntervalCount == 2) { - hoursInfo.detail = mContext.getString( - R.string.opening_hours, - getTimeSpanStringForHours(openingHours.get(0)), - getTimeSpanStringForHours(openingHours.get(1))); - } else if (afterInterval < openingHours.size()) { - // This check should not be necessary since if it is currently open, we should not - // be after the last interval, but just in case, we don't want to crash. - hoursInfo.detail = mContext.getString( - R.string.closes_today_at, - getFormattedTimeForCalendar(openingHours.get(afterInterval).second)); - } - } else { // Currently closed - final int lastIntervalToday = todaysIntervalCount - 1; - if (todaysIntervalCount == 0) { // closed today - hoursInfo.detail = mContext.getString( - R.string.opens_tomorrow_at, - getFormattedTimeForCalendar(openingHours.get(0).first)); - } else if (currentTime.after(openingHours.get(lastIntervalToday).second)) { - // Passed hours for today - if (todaysIntervalCount < openingHours.size()) { - // If all of today's intervals are exhausted, assume the next are tomorrow's. - hoursInfo.detail = mContext.getString( - R.string.opens_tomorrow_at, - getFormattedTimeForCalendar( - openingHours.get(todaysIntervalCount).first)); - } else { - // Grab the last time it was open today. - hoursInfo.detail = mContext.getString( - R.string.closed_today_at, - getFormattedTimeForCalendar( - openingHours.get(lastIntervalToday).second)); - } - } else if (afterInterval < openingHours.size()) { - // This check should not be necessary since if it is currently before the last - // interval, afterInterval should be less than the count of intervals, but just in - // case, we don't want to crash. - hoursInfo.detail = mContext.getString( - R.string.opens_today_at, - getFormattedTimeForCalendar(openingHours.get(afterInterval).first)); - } - } - - return hoursInfo; - } - - String getFormattedTimeForCalendar(Calendar calendar) { - return DateFormat.getTimeFormat(mContext).format(calendar.getTime()); - } - - String getTimeSpanStringForHours(Pair<Calendar, Calendar> hours) { - return mContext.getString(R.string.open_time_span, - getFormattedTimeForCalendar(hours.first), - getFormattedTimeForCalendar(hours.second)); - } - - /** - * Construct a BusinessContextInfo object with the location information of the business. - * The format is: - * [Straight line distance in miles or kilometers] - * [Address without state/country/etc.] - * - * @param address An Address object containing address details of the business - * @param distance The distance to the location in meters - * @return A BusinessContextInfo object with the location icon, the heading as the distance to - * the business and the details containing the address. - */ - private BusinessContextInfo constructLocationInfo(Address address, float distance) { - return constructLocationInfo(Locale.getDefault(), address, distance); - } - - @VisibleForTesting - BusinessContextInfo constructLocationInfo(Locale locale, Address address, - float distance) { - if (address == null) { - return null; - } - - BusinessContextInfo locationInfo = new BusinessContextInfo(); - locationInfo.iconId = R.drawable.ic_location_on_white_24dp; - if (distance != DistanceHelper.DISTANCE_NOT_FOUND) { - //TODO: add a setting to allow the user to select "KM" or "MI" as their distance units. - if (Locale.US.equals(locale)) { - locationInfo.heading = mContext.getString(R.string.distance_imperial_away, - distance * DistanceHelper.MILES_PER_METER); - } else { - locationInfo.heading = mContext.getString(R.string.distance_metric_away, - distance * DistanceHelper.KILOMETERS_PER_METER); - } - } - if (address.getLocality() != null) { - locationInfo.detail = mContext.getString( - R.string.display_address, - address.getAddressLine(0), - address.getLocality()); - } else { - locationInfo.detail = address.getAddressLine(0); - } - return locationInfo; - } - - /** - * Get the appropriate title for the context. - * @return The "Business info" title for a business contact and the "Recent messages" title for - * personal contacts. - */ - public String getContactContextTitle() { - return mIsBusiness - ? mContext.getResources().getString(R.string.business_contact_context_title) - : mContext.getResources().getString(R.string.person_contact_context_title); - } - - public static abstract class ContactContextInfo { - public abstract void bindView(View listItem); - } - - public static class BusinessContextInfo extends ContactContextInfo { - int iconId; - String heading; - String detail; - - @Override - public void bindView(View listItem) { - ImageView imageView = (ImageView) listItem.findViewById(R.id.icon); - TextView headingTextView = (TextView) listItem.findViewById(R.id.heading); - TextView detailTextView = (TextView) listItem.findViewById(R.id.detail); - - if (this.iconId == 0 || (this.heading == null && this.detail == null)) { - return; - } - - imageView.setImageDrawable(listItem.getContext().getDrawable(this.iconId)); - - headingTextView.setText(this.heading); - headingTextView.setVisibility(TextUtils.isEmpty(this.heading) - ? View.GONE : View.VISIBLE); - - detailTextView.setText(this.detail); - detailTextView.setVisibility(TextUtils.isEmpty(this.detail) - ? View.GONE : View.VISIBLE); - - } - } - - public static class PersonContextInfo extends ContactContextInfo { - boolean isIncoming; - String message; - String detail; - - @Override - public void bindView(View listItem) { - TextView messageTextView = (TextView) listItem.findViewById(R.id.message); - TextView detailTextView = (TextView) listItem.findViewById(R.id.detail); - - if (this.message == null || this.detail == null) { - return; - } - - messageTextView.setBackgroundResource(this.isIncoming ? - R.drawable.incoming_sms_background : R.drawable.outgoing_sms_background); - messageTextView.setText(this.message); - LayoutParams messageLayoutParams = (LayoutParams) messageTextView.getLayoutParams(); - messageLayoutParams.addRule(this.isIncoming? - RelativeLayout.ALIGN_PARENT_START : RelativeLayout.ALIGN_PARENT_END); - messageTextView.setLayoutParams(messageLayoutParams); - - LayoutParams detailLayoutParams = (LayoutParams) detailTextView.getLayoutParams(); - detailLayoutParams.addRule(this.isIncoming ? - RelativeLayout.ALIGN_PARENT_START : RelativeLayout.ALIGN_PARENT_END); - detailTextView.setLayoutParams(detailLayoutParams); - detailTextView.setText(this.detail); - } - } - - /** - * A list adapter for call context information. We use the same adapter for both business and - * contact context. - */ - private class InCallContactInteractionsListAdapter extends ArrayAdapter<ContactContextInfo> { - // The resource id of the list item layout. - int mResId; - - public InCallContactInteractionsListAdapter(Context context, int resource) { - super(context, resource); - mResId = resource; - } - - @Override - public View getView(int position, View convertView, ViewGroup parent) { - View listItem = mInflater.inflate(mResId, null); - ContactContextInfo item = getItem(position); - - if (item == null) { - return listItem; - } - - item.bindView(listItem); - return listItem; - } - } -} |