summaryrefslogtreecommitdiff
path: root/java/com/android/dialer/calllog
diff options
context:
space:
mode:
authorlinyuh <linyuh@google.com>2018-04-12 16:47:57 -0700
committerCopybara-Service <copybara-piper@google.com>2018-04-12 16:49:10 -0700
commit5a763afb48b2943d4bc7dd53b986e16bc103c44d (patch)
tree6e6568bab706ccd299e3b8dcdd93ca901bfd61a9 /java/com/android/dialer/calllog
parent0b3c523efdd58f884969e5d425dead5cecc41329 (diff)
Add Duo disclosure card to the new call log.
Bug: 70989614 Test: NewCallLogAdapterTest PiperOrigin-RevId: 192692744 Change-Id: I42dbb5738558803ad6eae9fe2c2f98b31c49f360
Diffstat (limited to 'java/com/android/dialer/calllog')
-rw-r--r--java/com/android/dialer/calllog/ui/DuoDisclosureCardViewHolder.java64
-rw-r--r--java/com/android/dialer/calllog/ui/NewCallLogAdapter.java111
-rw-r--r--java/com/android/dialer/calllog/ui/res/layout/new_call_log_duo_disclosure_card.xml82
-rw-r--r--java/com/android/dialer/calllog/ui/res/values/strings.xml17
4 files changed, 252 insertions, 22 deletions
diff --git a/java/com/android/dialer/calllog/ui/DuoDisclosureCardViewHolder.java b/java/com/android/dialer/calllog/ui/DuoDisclosureCardViewHolder.java
new file mode 100644
index 000000000..6b9112789
--- /dev/null
+++ b/java/com/android/dialer/calllog/ui/DuoDisclosureCardViewHolder.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2018 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.dialer.calllog.ui;
+
+import android.content.Context;
+import android.support.v7.widget.RecyclerView.ViewHolder;
+import android.text.method.LinkMovementMethod;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.TextView;
+import com.android.dialer.configprovider.ConfigProviderBindings;
+import com.android.dialer.duo.DuoComponent;
+import com.android.dialer.spannable.ContentWithLearnMoreSpanner;
+
+/** ViewHolder for {@link NewCallLogAdapter} to display the Duo disclosure card. */
+public class DuoDisclosureCardViewHolder extends ViewHolder {
+
+ private final Button okButton;
+
+ DuoDisclosureCardViewHolder(View itemView) {
+ super(itemView);
+
+ Context context = itemView.getContext();
+
+ // Set the Duo logo.
+ ImageView duoLogoView = itemView.findViewById(R.id.new_call_log_duo_disclosure_card_logo);
+ duoLogoView.setImageResource(DuoComponent.get(context).getDuo().getLogo());
+
+ // Set detailed text with a "learn more" link.
+ TextView cardDetailsView = itemView.findViewById(R.id.new_call_log_duo_disclosure_card_details);
+ cardDetailsView.setText(
+ new ContentWithLearnMoreSpanner(context)
+ .create(
+ context.getResources().getString(R.string.new_call_log_duo_disclosure_card_details),
+ ConfigProviderBindings.get(context)
+ .getString(
+ "duo_disclosure_link_full_url",
+ "http://support.google.com/pixelphone/?p=dialer_duo")));
+ cardDetailsView.setMovementMethod(LinkMovementMethod.getInstance()); // make the link clickable
+
+ // Obtain a reference to the "OK, got it" button.
+ okButton = itemView.findViewById(R.id.new_call_log_duo_disclosure_card_ok);
+ }
+
+ void setDismissListener(OnClickListener listener) {
+ okButton.setOnClickListener(listener);
+ }
+}
diff --git a/java/com/android/dialer/calllog/ui/NewCallLogAdapter.java b/java/com/android/dialer/calllog/ui/NewCallLogAdapter.java
index 839ba332f..22163774e 100644
--- a/java/com/android/dialer/calllog/ui/NewCallLogAdapter.java
+++ b/java/com/android/dialer/calllog/ui/NewCallLogAdapter.java
@@ -16,16 +16,21 @@
package com.android.dialer.calllog.ui;
import android.content.Context;
+import android.content.SharedPreferences;
import android.database.Cursor;
import android.support.annotation.IntDef;
import android.support.annotation.Nullable;
+import android.support.annotation.VisibleForTesting;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.RecyclerView.ViewHolder;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import com.android.dialer.calllogutils.CallLogDates;
import com.android.dialer.common.Assert;
+import com.android.dialer.duo.Duo;
+import com.android.dialer.duo.DuoComponent;
import com.android.dialer.logging.Logger;
+import com.android.dialer.storage.StorageComponent;
import com.android.dialer.time.Clock;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -33,31 +38,45 @@ import java.lang.annotation.RetentionPolicy;
/** {@link RecyclerView.Adapter} for the new call log fragment. */
final class NewCallLogAdapter extends RecyclerView.Adapter<ViewHolder> {
+ @VisibleForTesting
+ static final String SHARED_PREF_KEY_DUO_DISCLOSURE_DISMISSED = "duo_disclosure_dismissed";
+
/** IntDef for the different types of rows that can be shown in the call log. */
@Retention(RetentionPolicy.SOURCE)
@IntDef({
+ RowType.DUO_DISCLOSURE_CARD,
RowType.HEADER_TODAY,
RowType.HEADER_YESTERDAY,
RowType.HEADER_OLDER,
RowType.CALL_LOG_ENTRY
})
@interface RowType {
+ /** The Duo disclosure card. */
+ int DUO_DISCLOSURE_CARD = 1;
+
/** Header that displays "Today". */
- int HEADER_TODAY = 1;
+ int HEADER_TODAY = 2;
+
/** Header that displays "Yesterday". */
- int HEADER_YESTERDAY = 2;
+ int HEADER_YESTERDAY = 3;
+
/** Header that displays "Older". */
- int HEADER_OLDER = 3;
+ int HEADER_OLDER = 4;
+
/** A row representing a call log entry (which could represent one or more calls). */
- int CALL_LOG_ENTRY = 4;
+ int CALL_LOG_ENTRY = 5;
}
private final Clock clock;
+ private final Context context;
private final RealtimeRowProcessor realtimeRowProcessor;
private final PopCounts popCounts = new PopCounts();
private Cursor cursor;
+ /** Position of the Duo disclosure card. Null when it should not be displayed. */
+ @Nullable private Integer duoDisclosureCardPosition;
+
/** Position of the "Today" header. Null when it should not be displayed. */
@Nullable private Integer todayHeaderPosition;
@@ -68,11 +87,12 @@ final class NewCallLogAdapter extends RecyclerView.Adapter<ViewHolder> {
@Nullable private Integer olderHeaderPosition;
NewCallLogAdapter(Context context, Cursor cursor, Clock clock) {
+ this.context = context;
this.cursor = cursor;
this.clock = clock;
this.realtimeRowProcessor = CallLogUiComponent.get(context).realtimeRowProcessor();
- setHeaderPositions();
+ setCardAndHeaderPositions();
}
void updateCursor(Cursor updatedCursor) {
@@ -80,7 +100,7 @@ final class NewCallLogAdapter extends RecyclerView.Adapter<ViewHolder> {
this.realtimeRowProcessor.clearCache();
this.popCounts.reset();
- setHeaderPositions();
+ setCardAndHeaderPositions();
notifyDataSetChanged();
}
@@ -92,7 +112,15 @@ final class NewCallLogAdapter extends RecyclerView.Adapter<ViewHolder> {
Logger.get(context).logAnnotatedCallLogMetrics(popCounts.popped, popCounts.didNotPop);
}
- private void setHeaderPositions() {
+ private void setCardAndHeaderPositions() {
+ // Set the position for the Duo disclosure card if it should be shown.
+ duoDisclosureCardPosition = null;
+ int numCards = 0;
+ if (shouldShowDuoDisclosureCard()) {
+ duoDisclosureCardPosition = 0;
+ numCards++;
+ }
+
// If there are no rows to display, set all header positions to null.
if (!cursor.moveToFirst()) {
todayHeaderPosition = null;
@@ -101,6 +129,7 @@ final class NewCallLogAdapter extends RecyclerView.Adapter<ViewHolder> {
return;
}
+ // Calculate positions for headers.
long currentTimeMillis = clock.currentTimeMillis();
int numItemsInToday = 0;
@@ -126,24 +155,42 @@ final class NewCallLogAdapter extends RecyclerView.Adapter<ViewHolder> {
// Set all header positions.
// A header position will be null if there is no item to be displayed under that header.
- todayHeaderPosition = numItemsInToday > 0 ? 0 : null;
- yesterdayHeaderPosition = numItemsInYesterday > 0 ? numItemsInToday : null;
- olderHeaderPosition = !cursor.isAfterLast() ? numItemsInToday + numItemsInYesterday : null;
+ todayHeaderPosition = numItemsInToday > 0 ? numCards : null;
+ yesterdayHeaderPosition = numItemsInYesterday > 0 ? numItemsInToday + numCards : null;
+ olderHeaderPosition =
+ !cursor.isAfterLast() ? numItemsInToday + numItemsInYesterday + numCards : null;
+ }
+
+ private boolean shouldShowDuoDisclosureCard() {
+ Duo duo = DuoComponent.get(context).getDuo();
+ if (!duo.isEnabled(context) || !duo.isActivated(context)) {
+ return false;
+ }
+
+ SharedPreferences sharedPref = StorageComponent.get(context).unencryptedSharedPrefs();
+ return !sharedPref.getBoolean(SHARED_PREF_KEY_DUO_DISCLOSURE_DISMISSED, false);
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, @RowType int viewType) {
switch (viewType) {
+ case RowType.DUO_DISCLOSURE_CARD:
+ return new DuoDisclosureCardViewHolder(
+ LayoutInflater.from(context)
+ .inflate(
+ R.layout.new_call_log_duo_disclosure_card,
+ viewGroup,
+ /* attachToRoot = */ false));
case RowType.HEADER_TODAY:
case RowType.HEADER_YESTERDAY:
case RowType.HEADER_OLDER:
return new HeaderViewHolder(
- LayoutInflater.from(viewGroup.getContext())
- .inflate(R.layout.new_call_log_header, viewGroup, false));
+ LayoutInflater.from(context)
+ .inflate(R.layout.new_call_log_header, viewGroup, /* attachToRoot = */ false));
case RowType.CALL_LOG_ENTRY:
return new NewCallLogViewHolder(
- LayoutInflater.from(viewGroup.getContext())
- .inflate(R.layout.new_call_log_entry, viewGroup, false),
+ LayoutInflater.from(context)
+ .inflate(R.layout.new_call_log_entry, viewGroup, /* attachToRoot = */ false),
clock,
realtimeRowProcessor,
popCounts);
@@ -156,6 +203,19 @@ final class NewCallLogAdapter extends RecyclerView.Adapter<ViewHolder> {
public void onBindViewHolder(ViewHolder viewHolder, int position) {
@RowType int viewType = getItemViewType(position);
switch (viewType) {
+ case RowType.DUO_DISCLOSURE_CARD:
+ ((DuoDisclosureCardViewHolder) viewHolder)
+ .setDismissListener(
+ unused -> {
+ StorageComponent.get(context)
+ .unencryptedSharedPrefs()
+ .edit()
+ .putBoolean(SHARED_PREF_KEY_DUO_DISCLOSURE_DISMISSED, true)
+ .apply();
+ setCardAndHeaderPositions();
+ notifyDataSetChanged();
+ });
+ break;
case RowType.HEADER_TODAY:
((HeaderViewHolder) viewHolder).setHeader(R.string.new_call_log_header_today);
break;
@@ -167,17 +227,20 @@ final class NewCallLogAdapter extends RecyclerView.Adapter<ViewHolder> {
break;
case RowType.CALL_LOG_ENTRY:
NewCallLogViewHolder newCallLogViewHolder = (NewCallLogViewHolder) viewHolder;
- int previousHeaders = 0;
+ int previousCardAndHeaders = 0;
+ if (duoDisclosureCardPosition != null && position > duoDisclosureCardPosition) {
+ previousCardAndHeaders++;
+ }
if (todayHeaderPosition != null && position > todayHeaderPosition) {
- previousHeaders++;
+ previousCardAndHeaders++;
}
if (yesterdayHeaderPosition != null && position > yesterdayHeaderPosition) {
- previousHeaders++;
+ previousCardAndHeaders++;
}
if (olderHeaderPosition != null && position > olderHeaderPosition) {
- previousHeaders++;
+ previousCardAndHeaders++;
}
- cursor.moveToPosition(position - previousHeaders);
+ cursor.moveToPosition(position - previousCardAndHeaders);
newCallLogViewHolder.bind(cursor);
break;
default:
@@ -189,6 +252,9 @@ final class NewCallLogAdapter extends RecyclerView.Adapter<ViewHolder> {
@Override
@RowType
public int getItemViewType(int position) {
+ if (duoDisclosureCardPosition != null && position == duoDisclosureCardPosition) {
+ return RowType.DUO_DISCLOSURE_CARD;
+ }
if (todayHeaderPosition != null && position == todayHeaderPosition) {
return RowType.HEADER_TODAY;
}
@@ -203,7 +269,12 @@ final class NewCallLogAdapter extends RecyclerView.Adapter<ViewHolder> {
@Override
public int getItemCount() {
+ int numberOfCards = 0;
int numberOfHeaders = 0;
+
+ if (duoDisclosureCardPosition != null) {
+ numberOfCards++;
+ }
if (todayHeaderPosition != null) {
numberOfHeaders++;
}
@@ -213,7 +284,7 @@ final class NewCallLogAdapter extends RecyclerView.Adapter<ViewHolder> {
if (olderHeaderPosition != null) {
numberOfHeaders++;
}
- return cursor.getCount() + numberOfHeaders;
+ return cursor.getCount() + numberOfHeaders + numberOfCards;
}
static class PopCounts {
diff --git a/java/com/android/dialer/calllog/ui/res/layout/new_call_log_duo_disclosure_card.xml b/java/com/android/dialer/calllog/ui/res/layout/new_call_log_duo_disclosure_card.xml
new file mode 100644
index 000000000..1e24c8ba2
--- /dev/null
+++ b/java/com/android/dialer/calllog/ui/res/layout/new_call_log_duo_disclosure_card.xml
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2018 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
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:background="@color/background_dialer_light">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingTop="16dp"
+ android:paddingStart="16dp"
+ android:paddingEnd="24dp"
+ android:clipChildren="false"
+ android:clipToPadding="false"
+ android:orientation="horizontal">
+
+ <ImageView
+ android:id="@+id/new_call_log_duo_disclosure_card_logo"
+ android:layout_width="40dp"
+ android:layout_height="40dp"
+ android:layout_marginEnd="16dp"/>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="8dp"
+ android:orientation="vertical">
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="12dp"
+ android:fontFamily="sans-serif-medium"
+ android:text="@string/new_call_log_duo_disclosure_card_header"
+ android:textColor="@color/primary_material_dark"
+ android:textSize="@dimen/call_log_primary_text_size"/>
+ <TextView
+ android:id="@+id/new_call_log_duo_disclosure_card_details"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="16dp"
+ android:lineSpacingExtra="8dp"
+ android:textColor="@color/primary_material_dark"
+ android:textSize="14sp"/>
+ <Button
+ android:id="@+id/new_call_log_duo_disclosure_card_ok"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="6dp"
+ android:layout_marginBottom="2dp"
+ android:layout_gravity="end"
+ android:paddingLeft="14dp"
+ android:paddingRight="14dp"
+ android:text="@string/new_call_log_duo_disclosure_card_ok"
+ android:textSize="14sp"/>
+ </LinearLayout>
+ </LinearLayout>
+
+ <!-- The boundary line at the bottom -->
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="1dp"
+ android:layout_marginTop="8dp"
+ android:background="#DBDBDB"/>
+</LinearLayout>
diff --git a/java/com/android/dialer/calllog/ui/res/values/strings.xml b/java/com/android/dialer/calllog/ui/res/values/strings.xml
index ebddc3578..f04bffa3f 100644
--- a/java/com/android/dialer/calllog/ui/res/values/strings.xml
+++ b/java/com/android/dialer/calllog/ui/res/values/strings.xml
@@ -15,7 +15,7 @@
~ limitations under the License
-->
-<resources>
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<!-- Header in call log to group calls from the current day. [CHAR LIMIT=30] -->
<string name="new_call_log_header_today">Today</string>
@@ -26,4 +26,17 @@
<!-- Header in call log to group calls from before yesterday. [CHAR LIMIT=30] -->
<string name="new_call_log_header_older">Older</string>
-</resources> \ No newline at end of file
+ <!-- Header on the Duo disclosure card. [CHAR_LIMIT=60] -->
+ <string name="new_call_log_duo_disclosure_card_header">
+ Make video calls with Duo
+ </string>
+
+ <!-- Details on the Duo disclosure card. [CHAR_LIMIT=200] -->
+ <string name="new_call_log_duo_disclosure_card_details">
+ Google Duo video calling lets you chat with friends and family face-to-face. Data charges may apply. <xliff:g example="Learn More">%1$s</xliff:g>
+ </string>
+
+ <!-- Text on the button on the Duo disclosure card. [CHAR_LIMIT=30] -->
+ <string name="new_call_log_duo_disclosure_card_ok">OK, got it</string>
+
+</resources>