diff options
author | Treehugger Robot <treehugger-gerrit@google.com> | 2018-05-11 20:18:46 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2018-05-11 20:18:46 +0000 |
commit | 14ceb5d6cee235b772f5f3dba38802665f12ab66 (patch) | |
tree | 4e43dc9a6d507693e68e9fe32eba0201b843888b /java/com/android | |
parent | ced93f2d22bffce3b4cfb9c3bfce862b385537dd (diff) | |
parent | ef5c101361fc4cf23c12aa7ef24d027155b7554a (diff) |
Merge changes Ie424d231,Ied6072ca,I1902e527,Ie649a9fb,I11fc1a02, ...
* changes:
Use old BottomSheetBehavior.
Use listeners to drive fragment lifecycles.
Add SpamMetadata to SpamStatus
Prevent showDialpad from adding multiple instances of fragments
Update logging in incallactivity.
Revert null check on dialpadHint
Add @InstallIn and @IncludeInDialerRoot to dagger modules in dialer codebase.
Add RTT after call promo bottomsheet.
Diffstat (limited to 'java/com/android')
39 files changed, 489 insertions, 58 deletions
diff --git a/java/com/android/dialer/calllog/CallLogModule.java b/java/com/android/dialer/calllog/CallLogModule.java index 56572705d..0e3a3be9e 100644 --- a/java/com/android/dialer/calllog/CallLogModule.java +++ b/java/com/android/dialer/calllog/CallLogModule.java @@ -22,11 +22,14 @@ import com.android.dialer.calllog.datasources.DataSources; import com.android.dialer.calllog.datasources.phonelookup.PhoneLookupDataSource; import com.android.dialer.calllog.datasources.systemcalllog.SystemCallLogDataSource; import com.android.dialer.calllog.datasources.voicemail.VoicemailDataSource; +import com.android.dialer.inject.DialerVariant; +import com.android.dialer.inject.InstallIn; import com.google.common.collect.ImmutableList; import dagger.Module; import dagger.Provides; /** Dagger module which satisfies call log dependencies. */ +@InstallIn(variants = {DialerVariant.DIALER_TEST}) @Module(includes = CallLogDatabaseModule.class) public abstract class CallLogModule { diff --git a/java/com/android/dialer/calllog/ui/NewCallLogAdapter.java b/java/com/android/dialer/calllog/ui/NewCallLogAdapter.java index 7fd8132aa..69cc02be4 100644 --- a/java/com/android/dialer/calllog/ui/NewCallLogAdapter.java +++ b/java/com/android/dialer/calllog/ui/NewCallLogAdapter.java @@ -31,6 +31,7 @@ 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.promotion.RttPromotion; import com.android.dialer.storage.StorageComponent; import com.android.dialer.time.Clock; import java.lang.annotation.Retention; @@ -173,6 +174,9 @@ final class NewCallLogAdapter extends RecyclerView.Adapter<ViewHolder> { } private boolean shouldShowDuoDisclosureCard() { + if (new RttPromotion(activity).shouldShow()) { + return false; + } // Don't show the Duo disclosure card if // (1) Duo integration is not enabled on the device, or // (2) Duo is not activated. 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 index 1e24c8ba2..a28101c6f 100644 --- 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 @@ -68,7 +68,7 @@ android:layout_gravity="end" android:paddingLeft="14dp" android:paddingRight="14dp" - android:text="@string/new_call_log_duo_disclosure_card_ok" + android:text="@string/ok_got_it" android:textSize="14sp"/> </LinearLayout> </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 f04bffa3f..ec8d59503 100644 --- a/java/com/android/dialer/calllog/ui/res/values/strings.xml +++ b/java/com/android/dialer/calllog/ui/res/values/strings.xml @@ -36,7 +36,4 @@ 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> diff --git a/java/com/android/dialer/commandline/CommandLineComponent.java b/java/com/android/dialer/commandline/CommandLineComponent.java index c9abc532d..50a1ff2b2 100644 --- a/java/com/android/dialer/commandline/CommandLineComponent.java +++ b/java/com/android/dialer/commandline/CommandLineComponent.java @@ -19,6 +19,7 @@ package com.android.dialer.commandline; import android.content.Context; import com.android.dialer.function.Supplier; import com.android.dialer.inject.HasRootComponent; +import com.android.dialer.inject.IncludeInDialerRoot; import com.google.common.collect.ImmutableMap; import dagger.Subcomponent; @@ -34,6 +35,7 @@ public abstract class CommandLineComponent { } /** Used to refer to the root application component. */ + @IncludeInDialerRoot public interface HasComponent { CommandLineComponent commandLineComponent(); } diff --git a/java/com/android/dialer/commandline/CommandLineModule.java b/java/com/android/dialer/commandline/CommandLineModule.java index c78de21e5..c3b58d1d5 100644 --- a/java/com/android/dialer/commandline/CommandLineModule.java +++ b/java/com/android/dialer/commandline/CommandLineModule.java @@ -23,12 +23,15 @@ import com.android.dialer.commandline.impl.Echo; import com.android.dialer.commandline.impl.Help; import com.android.dialer.commandline.impl.Version; import com.android.dialer.function.Supplier; +import com.android.dialer.inject.DialerVariant; +import com.android.dialer.inject.InstallIn; import com.google.common.collect.ImmutableMap; import dagger.Module; import dagger.Provides; import javax.inject.Inject; /** Provides {@link Command} */ +@InstallIn(variants = {DialerVariant.DIALER_TEST}) @Module public abstract class CommandLineModule { diff --git a/java/com/android/dialer/common/res/values/strings.xml b/java/com/android/dialer/common/res/values/strings.xml index cc0594dee..3bd21d5c1 100644 --- a/java/com/android/dialer/common/res/values/strings.xml +++ b/java/com/android/dialer/common/res/values/strings.xml @@ -21,4 +21,6 @@ <string name="content_description_overflow">More options</string> <!-- Text for undo button in snackbar for voicemail deletion/blocking/unblocking number. [CHAR LIMIT=10] --> <string name="snackbar_undo">UNDO</string> + <!-- Text on button of "OK, got it". [CHAR_LIMIT=30] --> + <string name="ok_got_it">OK, got it</string> </resources> diff --git a/java/com/android/dialer/configprovider/SharedPrefConfigProvider.java b/java/com/android/dialer/configprovider/SharedPrefConfigProvider.java index 54e9c9aff..c68312f56 100644 --- a/java/com/android/dialer/configprovider/SharedPrefConfigProvider.java +++ b/java/com/android/dialer/configprovider/SharedPrefConfigProvider.java @@ -102,6 +102,10 @@ public class SharedPrefConfigProvider implements ConfigProvider { sharedPreferences.edit().putLong(PREF_PREFIX + key, value).apply(); } + public void putString(String key, String value) { + sharedPreferences.edit().putString(PREF_PREFIX + key, value).apply(); + } + @Override public String getString(String key, String defaultValue) { // Reading shared prefs on the main thread is generally safe since a single instance is cached. diff --git a/java/com/android/dialer/dialpadview/DialpadFragment.java b/java/com/android/dialer/dialpadview/DialpadFragment.java index d48870dfc..8fb7533f4 100644 --- a/java/com/android/dialer/dialpadview/DialpadFragment.java +++ b/java/com/android/dialer/dialpadview/DialpadFragment.java @@ -478,12 +478,7 @@ public class DialpadFragment extends Fragment } digits.setContentDescription(null); - // TOOD(77908301): Investigate why this is the case - // It's not clear why digitsHint would be null when digits is initialized as the time, so adding - // a todo to investigate why. - if (digitsHint != null) { - digitsHint.setVisibility(View.GONE); - } + digitsHint.setVisibility(View.GONE); } /** diff --git a/java/com/android/dialer/feedback/stub/StubFeedbackModule.java b/java/com/android/dialer/feedback/stub/StubFeedbackModule.java index 49df09a04..19f7e2e6c 100644 --- a/java/com/android/dialer/feedback/stub/StubFeedbackModule.java +++ b/java/com/android/dialer/feedback/stub/StubFeedbackModule.java @@ -20,6 +20,8 @@ import android.content.Context; import com.android.dialer.common.LogUtil; import com.android.dialer.feedback.FeedbackSender; import com.android.dialer.inject.ApplicationContext; +import com.android.dialer.inject.DialerVariant; +import com.android.dialer.inject.InstallIn; import com.android.dialer.logging.LoggingBindings; import com.android.dialer.logging.LoggingBindingsFactory; import com.android.dialer.logging.LoggingBindingsStub; @@ -28,6 +30,7 @@ import dagger.Module; import dagger.Provides; /** Module which bind {@link com.android.dialer.feedback.stub.CallFeedbackListenerStub}. */ +@InstallIn(variants = {DialerVariant.DIALER_TEST}) @Module public class StubFeedbackModule { diff --git a/java/com/android/dialer/glidephotomanager/GlidePhotoManagerModule.java b/java/com/android/dialer/glidephotomanager/GlidePhotoManagerModule.java index 79629d69e..d4199f0a8 100644 --- a/java/com/android/dialer/glidephotomanager/GlidePhotoManagerModule.java +++ b/java/com/android/dialer/glidephotomanager/GlidePhotoManagerModule.java @@ -17,11 +17,14 @@ package com.android.dialer.glidephotomanager; import com.android.dialer.glidephotomanager.impl.GlidePhotoManagerImpl; +import com.android.dialer.inject.DialerVariant; +import com.android.dialer.inject.InstallIn; import dagger.Binds; import dagger.Module; import javax.inject.Singleton; /** Module for {@link GlidePhotoManagerComponent} */ +@InstallIn(variants = {DialerVariant.DIALER_TEST}) @Module public abstract class GlidePhotoManagerModule { @Binds diff --git a/java/com/android/dialer/main/impl/MainSearchController.java b/java/com/android/dialer/main/impl/MainSearchController.java index 72c46cc7a..7d476c8f6 100644 --- a/java/com/android/dialer/main/impl/MainSearchController.java +++ b/java/com/android/dialer/main/impl/MainSearchController.java @@ -23,6 +23,7 @@ import android.content.Intent; import android.os.Bundle; import android.speech.RecognizerIntent; import android.support.annotation.Nullable; +import android.support.annotation.VisibleForTesting; import android.support.design.widget.FloatingActionButton; import android.support.v7.app.AppCompatActivity; import android.text.TextUtils; @@ -98,6 +99,9 @@ public class MainSearchController implements SearchBarListener { private boolean callPlacedFromSearch; private boolean requestingPermission; + private DialpadFragment dialpadFragment; + private NewSearchFragment searchFragment; + public MainSearchController( TransactionSafeActivity activity, BottomNavBar bottomNav, @@ -122,7 +126,7 @@ public class MainSearchController implements SearchBarListener { LogUtil.i("MainSearchController.showDialpadFromNewIntent", "Dialpad is already visible."); // Mark started from new intent in case there is a phone number in the intent - getDialpadFragment().setStartedFromNewIntent(true); + dialpadFragment.setStartedFromNewIntent(true); return; } showDialpad(/* animate=*/ false, /* fromNewIntent=*/ true); @@ -150,7 +154,6 @@ public class MainSearchController implements SearchBarListener { activity.setTitle(R.string.dialpad_activity_title); FragmentTransaction transaction = activity.getFragmentManager().beginTransaction(); - NewSearchFragment searchFragment = getSearchFragment(); // Show Search if (searchFragment == null) { @@ -162,16 +165,14 @@ public class MainSearchController implements SearchBarListener { } // Show Dialpad - if (getDialpadFragment() == null) { - DialpadFragment dialpadFragment = new DialpadFragment(); + if (dialpadFragment == null) { + dialpadFragment = new DialpadFragment(); dialpadFragment.setStartedFromNewIntent(fromNewIntent); transaction.add(R.id.dialpad_fragment_container, dialpadFragment, DIALPAD_FRAGMENT_TAG); searchFragment.setQuery("", CallInitiationType.Type.DIALPAD); } else { - DialpadFragment dialpadFragment = getDialpadFragment(); dialpadFragment.setStartedFromNewIntent(fromNewIntent); transaction.show(dialpadFragment); - searchFragment.setQuery(dialpadFragment.getQuery(), CallInitiationType.Type.DIALPAD); } transaction.commit(); @@ -189,7 +190,6 @@ public class MainSearchController implements SearchBarListener { */ private void hideDialpad(boolean animate) { LogUtil.enterBlock("MainSearchController.hideDialpad"); - DialpadFragment dialpadFragment = getDialpadFragment(); if (dialpadFragment == null) { LogUtil.e("MainSearchController.hideDialpad", "Dialpad fragment is null."); return; @@ -212,7 +212,7 @@ public class MainSearchController implements SearchBarListener { fab.show(); toolbar.slideDown(animate, fragmentContainer); - toolbar.transferQueryFromDialpad(getDialpadFragment().getQuery()); + toolbar.transferQueryFromDialpad(dialpadFragment.getQuery()); activity.setTitle(R.string.main_activity_label); dialpadFragment.setAnimate(animate); @@ -246,7 +246,7 @@ public class MainSearchController implements SearchBarListener { /** Should be called when {@link DialpadListener#onDialpadShown()} is called. */ public void onDialpadShown() { LogUtil.enterBlock("MainSearchController.onDialpadShown"); - getDialpadFragment().slideUp(true); + dialpadFragment.slideUp(true); hideBottomNav(); } @@ -263,7 +263,7 @@ public class MainSearchController implements SearchBarListener { public void onSearchListTouch() { LogUtil.enterBlock("MainSearchController.onSearchListTouched"); if (isDialpadVisible()) { - if (TextUtils.isEmpty(getDialpadFragment().getQuery())) { + if (TextUtils.isEmpty(dialpadFragment.getQuery())) { Logger.get(activity) .logImpression( DialerImpression.Type.MAIN_TOUCH_DIALPAD_SEARCH_LIST_TO_CLOSE_SEARCH_AND_DIALPAD); @@ -292,7 +292,7 @@ public class MainSearchController implements SearchBarListener { * @return true if #onBackPressed() handled to action. */ public boolean onBackPressed() { - if (isDialpadVisible() && !TextUtils.isEmpty(getDialpadFragment().getQuery())) { + if (isDialpadVisible() && !TextUtils.isEmpty(dialpadFragment.getQuery())) { LogUtil.i("MainSearchController.onBackPressed", "Dialpad visible with query"); Logger.get(activity) .logImpression(DialerImpression.Type.MAIN_PRESS_BACK_BUTTON_TO_HIDE_DIALPAD); @@ -315,7 +315,6 @@ public class MainSearchController implements SearchBarListener { /** Calls {@link #hideDialpad(boolean)}, removes the search fragment and clears the dialpad. */ private void closeSearch(boolean animate) { LogUtil.enterBlock("MainSearchController.closeSearch"); - NewSearchFragment searchFragment = getSearchFragment(); if (searchFragment == null) { LogUtil.e("MainSearchController.closeSearch", "Search fragment is null."); return; @@ -342,7 +341,6 @@ public class MainSearchController implements SearchBarListener { activity.getFragmentManager().beginTransaction().hide(searchFragment).commit(); // Clear the dialpad so the phone number isn't persisted between search sessions. - DialpadFragment dialpadFragment = getDialpadFragment(); if (dialpadFragment != null) { // Temporarily disable accessibility when we clear the dialpad, since it should be // invisible and should not announce anything. @@ -360,25 +358,18 @@ public class MainSearchController implements SearchBarListener { @Nullable protected DialpadFragment getDialpadFragment() { - return (DialpadFragment) activity.getFragmentManager().findFragmentByTag(DIALPAD_FRAGMENT_TAG); - } - - @Nullable - private NewSearchFragment getSearchFragment() { - return (NewSearchFragment) activity.getFragmentManager().findFragmentByTag(SEARCH_FRAGMENT_TAG); + return dialpadFragment; } private boolean isDialpadVisible() { - DialpadFragment fragment = getDialpadFragment(); - return fragment != null - && fragment.isAdded() - && !fragment.isHidden() - && fragment.isDialpadSlideUp(); + return dialpadFragment != null + && dialpadFragment.isAdded() + && !dialpadFragment.isHidden() + && dialpadFragment.isDialpadSlideUp(); } private boolean isSearchVisible() { - NewSearchFragment fragment = getSearchFragment(); - return fragment != null && fragment.isAdded() && !fragment.isHidden(); + return searchFragment != null && searchFragment.isAdded() && !searchFragment.isHidden(); } /** Returns true if the search UI is visible. */ @@ -388,8 +379,7 @@ public class MainSearchController implements SearchBarListener { /** Closes the keyboard if necessary. */ private void closeKeyboard() { - NewSearchFragment fragment = getSearchFragment(); - if (fragment != null && fragment.isAdded()) { + if (searchFragment != null && searchFragment.isAdded()) { toolbar.hideKeyboard(); } } @@ -418,15 +408,13 @@ public class MainSearchController implements SearchBarListener { hideBottomNav(); FragmentTransaction transaction = activity.getFragmentManager().beginTransaction(); - NewSearchFragment searchFragment = getSearchFragment(); - // Show Search if (searchFragment == null) { searchFragment = NewSearchFragment.newInstance(); transaction.add(R.id.search_fragment_container, searchFragment, SEARCH_FRAGMENT_TAG); transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE); } else if (!isSearchVisible()) { - transaction.show(getSearchFragment()); + transaction.show(searchFragment); } searchFragment.setQuery( @@ -444,20 +432,18 @@ public class MainSearchController implements SearchBarListener { @Override public void onSearchQueryUpdated(String query) { - NewSearchFragment fragment = getSearchFragment(); - if (fragment != null) { - fragment.setQuery(query, CallInitiationType.Type.REGULAR_SEARCH); + if (searchFragment != null) { + searchFragment.setQuery(query, CallInitiationType.Type.REGULAR_SEARCH); } } /** @see OnDialpadQueryChangedListener#onDialpadQueryChanged(java.lang.String) */ public void onDialpadQueryChanged(String query) { query = SmartDialNameMatcher.normalizeNumber(/* context = */ activity, query); - NewSearchFragment fragment = getSearchFragment(); - if (fragment != null) { - fragment.setQuery(query, CallInitiationType.Type.DIALPAD); + if (searchFragment != null) { + searchFragment.setQuery(query, CallInitiationType.Type.DIALPAD); } - getDialpadFragment().process_quote_emergency_unquote(query); + dialpadFragment.process_quote_emergency_unquote(query); } @Override @@ -589,4 +575,14 @@ public class MainSearchController implements SearchBarListener { void onSearchClose(); } + + @VisibleForTesting + void setDialpadFragment(DialpadFragment dialpadFragment) { + this.dialpadFragment = dialpadFragment; + } + + @VisibleForTesting + void setSearchFragment(NewSearchFragment searchFragment) { + this.searchFragment = searchFragment; + } } diff --git a/java/com/android/dialer/main/impl/OldMainActivityPeer.java b/java/com/android/dialer/main/impl/OldMainActivityPeer.java index e426ed215..2d6b0a6e7 100644 --- a/java/com/android/dialer/main/impl/OldMainActivityPeer.java +++ b/java/com/android/dialer/main/impl/OldMainActivityPeer.java @@ -36,6 +36,7 @@ import android.provider.ContactsContract.QuickContact; import android.provider.VoicemailContract; import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import android.support.design.widget.BottomSheetBehavior; import android.support.design.widget.FloatingActionButton; import android.support.design.widget.Snackbar; import android.support.v4.content.ContextCompat; @@ -46,9 +47,11 @@ import android.telecom.PhoneAccount; import android.telecom.PhoneAccountHandle; import android.telephony.TelephonyManager; import android.text.TextUtils; +import android.text.method.LinkMovementMethod; import android.view.DragEvent; import android.view.View; import android.widget.ImageView; +import android.widget.TextView; import com.android.contacts.common.list.OnPhoneNumberPickerActionListener; import com.android.dialer.animation.AnimUtils; import com.android.dialer.app.DialtactsActivity; @@ -104,6 +107,8 @@ import com.android.dialer.metrics.Metrics; import com.android.dialer.metrics.MetricsComponent; import com.android.dialer.postcall.PostCall; import com.android.dialer.precall.PreCall; +import com.android.dialer.promotion.Promotion; +import com.android.dialer.promotion.RttPromotion; import com.android.dialer.searchfragment.list.NewSearchFragment.SearchFragmentListener; import com.android.dialer.smartdial.util.SmartDialPrefix; import com.android.dialer.speeddial.SpeedDialFragment; @@ -196,6 +201,7 @@ public class OldMainActivityPeer implements MainActivityPeer, FragmentUtilListen private MissedCallCountObserver missedCallCountObserver; private UiListener<String> getLastOutgoingCallListener; private UiListener<Integer> missedCallObserverUiListener; + private View bottomSheet; public static Intent getShowTabIntent(Context context, @TabIndex int tabIndex) { Intent intent = new Intent(context, MainActivity.class); @@ -240,6 +246,9 @@ public class OldMainActivityPeer implements MainActivityPeer, FragmentUtilListen dialpadFragmentHostInterface = new MainDialpadFragmentHost(); snackbarContainer = activity.findViewById(R.id.coordinator_layout); + bottomSheet = activity.findViewById(R.id.promotion_bottom_sheet); + BottomSheetBehavior<View> bottomSheetBehavior = BottomSheetBehavior.from(bottomSheet); + bottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN); FloatingActionButton fab = activity.findViewById(R.id.fab); fab.setOnClickListener( @@ -255,7 +264,11 @@ public class OldMainActivityPeer implements MainActivityPeer, FragmentUtilListen bottomNav = activity.findViewById(R.id.bottom_nav_bar); bottomNavTabListener = new MainBottomNavBarBottomNavTabListener( - activity, activity.getFragmentManager(), activity.getSupportFragmentManager(), fab); + activity, + activity.getFragmentManager(), + activity.getSupportFragmentManager(), + fab, + bottomSheet); bottomNav.addOnTabSelectedListener(bottomNavTabListener); // TODO(uabdullah): Handle case of when a sim is inserted/removed while the activity is open. boolean showVoicemailTab = canVoicemailTabBeShown(activity); @@ -1245,6 +1258,7 @@ public class OldMainActivityPeer implements MainActivityPeer, FragmentUtilListen private final FragmentManager fragmentManager; private final android.support.v4.app.FragmentManager supportFragmentManager; private final FloatingActionButton fab; + private final View bottomSheet; @TabIndex private int selectedTab = -1; @@ -1252,11 +1266,13 @@ public class OldMainActivityPeer implements MainActivityPeer, FragmentUtilListen TransactionSafeActivity activity, FragmentManager fragmentManager, android.support.v4.app.FragmentManager supportFragmentManager, - FloatingActionButton fab) { + FloatingActionButton fab, + View bottomSheet) { this.activity = activity; this.fragmentManager = fragmentManager; this.supportFragmentManager = supportFragmentManager; this.fab = fab; + this.bottomSheet = bottomSheet; } @Override @@ -1300,6 +1316,34 @@ public class OldMainActivityPeer implements MainActivityPeer, FragmentUtilListen showFragment(fragment == null ? new CallLogFragment() : fragment, CALL_LOG_TAG); } fab.show(); + showPromotionBottomSheet(activity, bottomSheet); + } + + private static void showPromotionBottomSheet(Context context, View view) { + // TODO(a bug): Use a promotion manager to get promotion to show. + Promotion promotion = new RttPromotion(context); + BottomSheetBehavior<View> bottomSheetBehavior = BottomSheetBehavior.from(view); + + if (!promotion.shouldShow()) { + bottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN); + return; + } + ImageView icon = view.findViewById(R.id.promotion_icon); + icon.setImageResource(promotion.getIconRes()); + TextView details = view.findViewById(R.id.promotion_details); + details.setText(promotion.getDetails()); + // Required to make link clickable. + details.setMovementMethod(LinkMovementMethod.getInstance()); + TextView title = view.findViewById(R.id.promotion_title); + title.setText(promotion.getTitle()); + view.findViewById(R.id.ok_got_it) + .setOnClickListener( + v -> { + promotion.dismiss(); + bottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN); + }); + view.setVisibility(View.VISIBLE); + bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED); } void disableNewCallLogFragment() { diff --git a/java/com/android/dialer/main/impl/res/layout/main_activity.xml b/java/com/android/dialer/main/impl/res/layout/main_activity.xml index a1d6e5372..b47806ece 100644 --- a/java/com/android/dialer/main/impl/res/layout/main_activity.xml +++ b/java/com/android/dialer/main/impl/res/layout/main_activity.xml @@ -63,6 +63,9 @@ android:src="@drawable/quantum_ic_dialpad_white_24" android:contentDescription="@string/dialpad_button_content_description" app:backgroundTint="?android:attr/colorAccent"/> + + <include android:id="@+id/promotion_bottom_sheet" + layout="@layout/promotion_bottom_sheet"/> </android.support.design.widget.CoordinatorLayout> <!-- BottomNavBar --> diff --git a/java/com/android/dialer/main/impl/res/layout/promotion_bottom_sheet.xml b/java/com/android/dialer/main/impl/res/layout/promotion_bottom_sheet.xml new file mode 100644 index 000000000..3f1e709fb --- /dev/null +++ b/java/com/android/dialer/main/impl/res/layout/promotion_bottom_sheet.xml @@ -0,0 +1,81 @@ +<?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" + xmlns:app="http://schemas.android.com/apk/res-auto" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:paddingTop="24dp" + android:paddingBottom="8dp" + android:paddingStart="16dp" + android:paddingEnd="24dp" + android:background="#FAFAFA" + android:clickable="true" + android:elevation="8dp" + android:orientation="horizontal" + android:visibility="gone" + app:behavior_hideable="true" + app:behavior_skipCollapsed="true" + app:layout_behavior="android.support.design.widget.BottomSheetBehavior" + app:layout_insetEdge="bottom"> + + <ImageView + android:id="@+id/promotion_icon" + android:layout_width="36dp" + android:layout_height="36dp" + android:tint="@color/dialer_theme_color"/> + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:paddingStart="32dp" + android:orientation="vertical"> + <TextView + android:id="@+id/promotion_title" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:fontFamily="sans-serif-medium" + android:textColor="#DD000000" + android:textSize="16sp" + /> + <TextView + android:id="@+id/promotion_details" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="8dp" + android:layout_marginBottom="16dp" + android:lineSpacingMultiplier="1.5" + android:textColor="#DD000000" + android:textSize="14sp"/> + <Button + android:id="@+id/ok_got_it" + style="@style/Widget.AppCompat.Button" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="8dp" + android:layout_marginBottom="8dp" + android:layout_gravity="end" + android:paddingStart="16dp" + android:paddingEnd="16dp" + android:backgroundTint="@color/dialer_theme_color" + android:fontFamily="sans-serif-medium" + android:stateListAnimator="@null" + android:text="@string/ok_got_it" + android:textColor="@android:color/white" + android:textSize="16sp"/> + </LinearLayout> + +</LinearLayout>
\ No newline at end of file diff --git a/java/com/android/dialer/metrics/StubMetricsModule.java b/java/com/android/dialer/metrics/StubMetricsModule.java index a2d9ebfe2..46b2b4d84 100644 --- a/java/com/android/dialer/metrics/StubMetricsModule.java +++ b/java/com/android/dialer/metrics/StubMetricsModule.java @@ -16,10 +16,13 @@ package com.android.dialer.metrics; +import com.android.dialer.inject.DialerVariant; +import com.android.dialer.inject.InstallIn; import dagger.Binds; import dagger.Module; /** Binds stub {@link Metrics}. */ +@InstallIn(variants = {DialerVariant.DIALER_TEST}) @Module public interface StubMetricsModule { diff --git a/java/com/android/dialer/phonelookup/PhoneLookupComponent.java b/java/com/android/dialer/phonelookup/PhoneLookupComponent.java index 832587c81..70743c84d 100644 --- a/java/com/android/dialer/phonelookup/PhoneLookupComponent.java +++ b/java/com/android/dialer/phonelookup/PhoneLookupComponent.java @@ -17,6 +17,7 @@ package com.android.dialer.phonelookup; import android.content.Context; import com.android.dialer.inject.HasRootComponent; +import com.android.dialer.inject.IncludeInDialerRoot; import com.android.dialer.phonelookup.composite.CompositePhoneLookup; import dagger.Subcomponent; @@ -32,6 +33,7 @@ public abstract class PhoneLookupComponent { } /** Used to refer to the root application component. */ + @IncludeInDialerRoot public interface HasComponent { PhoneLookupComponent phoneLookupComponent(); } diff --git a/java/com/android/dialer/phonelookup/PhoneLookupModule.java b/java/com/android/dialer/phonelookup/PhoneLookupModule.java index 16aa8e516..6d5ffd2ec 100644 --- a/java/com/android/dialer/phonelookup/PhoneLookupModule.java +++ b/java/com/android/dialer/phonelookup/PhoneLookupModule.java @@ -16,6 +16,8 @@ package com.android.dialer.phonelookup; +import com.android.dialer.inject.DialerVariant; +import com.android.dialer.inject.InstallIn; import com.android.dialer.phonelookup.blockednumber.SystemBlockedNumberPhoneLookup; import com.android.dialer.phonelookup.cequint.CequintPhoneLookup; import com.android.dialer.phonelookup.cnap.CnapPhoneLookup; @@ -28,6 +30,7 @@ import dagger.Module; import dagger.Provides; /** Dagger module which binds the PhoneLookup implementation. */ +@InstallIn(variants = {DialerVariant.DIALER_TEST}) @Module public abstract class PhoneLookupModule { diff --git a/java/com/android/dialer/phonenumbergeoutil/impl/PhoneNumberGeoUtilModule.java b/java/com/android/dialer/phonenumbergeoutil/impl/PhoneNumberGeoUtilModule.java index 3878ac508..db4f7fa43 100644 --- a/java/com/android/dialer/phonenumbergeoutil/impl/PhoneNumberGeoUtilModule.java +++ b/java/com/android/dialer/phonenumbergeoutil/impl/PhoneNumberGeoUtilModule.java @@ -16,12 +16,15 @@ package com.android.dialer.phonenumbergeoutil.impl; +import com.android.dialer.inject.DialerVariant; +import com.android.dialer.inject.InstallIn; import com.android.dialer.phonenumbergeoutil.PhoneNumberGeoUtil; import dagger.Binds; import dagger.Module; import javax.inject.Singleton; /** Module which binds {@link PhoneNumberGeoUtilImpl}. */ +@InstallIn(variants = {DialerVariant.DIALER_TEST}) @Module public abstract class PhoneNumberGeoUtilModule { diff --git a/java/com/android/dialer/precall/impl/PreCallModule.java b/java/com/android/dialer/precall/impl/PreCallModule.java index 455453ef3..fa78cba5c 100644 --- a/java/com/android/dialer/precall/impl/PreCallModule.java +++ b/java/com/android/dialer/precall/impl/PreCallModule.java @@ -16,6 +16,8 @@ package com.android.dialer.precall.impl; +import com.android.dialer.inject.DialerVariant; +import com.android.dialer.inject.InstallIn; import com.android.dialer.precall.PreCall; import com.android.dialer.precall.PreCallAction; import com.google.common.collect.ImmutableList; @@ -25,6 +27,7 @@ import dagger.Provides; import javax.inject.Singleton; /** Dagger module for {@link PreCall}. */ +@InstallIn(variants = {DialerVariant.DIALER_TEST}) @Module public abstract class PreCallModule { diff --git a/java/com/android/dialer/promotion/AndroidManifest.xml b/java/com/android/dialer/promotion/AndroidManifest.xml new file mode 100644 index 000000000..bd85b104f --- /dev/null +++ b/java/com/android/dialer/promotion/AndroidManifest.xml @@ -0,0 +1,16 @@ +<!-- + ~ 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 + --> +<manifest package="com.android.dialer.promotion"/> diff --git a/java/com/android/dialer/promotion/Promotion.java b/java/com/android/dialer/promotion/Promotion.java new file mode 100644 index 000000000..3cd16d4a6 --- /dev/null +++ b/java/com/android/dialer/promotion/Promotion.java @@ -0,0 +1,39 @@ +/* + * 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.promotion; + +import android.support.annotation.DrawableRes; + +/** Interface for promotion bottom sheet. */ +public interface Promotion { + + /** Returns if this promotion should be shown. */ + boolean shouldShow(); + + /** Sets to show this promotion. */ + void setShouldShow(boolean shouldShow); + + /** Dismisses this promotion. This is called when user acknowledged the promotion. */ + void dismiss(); + + CharSequence getTitle(); + + CharSequence getDetails(); + + @DrawableRes + int getIconRes(); +} diff --git a/java/com/android/dialer/promotion/RttPromotion.java b/java/com/android/dialer/promotion/RttPromotion.java new file mode 100644 index 000000000..feb6e4734 --- /dev/null +++ b/java/com/android/dialer/promotion/RttPromotion.java @@ -0,0 +1,84 @@ +/* + * 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.promotion; + +import android.content.Context; +import android.content.SharedPreferences; +import android.support.annotation.DrawableRes; +import com.android.dialer.common.LogUtil; +import com.android.dialer.configprovider.ConfigProviderBindings; +import com.android.dialer.spannable.ContentWithLearnMoreSpanner; +import com.android.dialer.storage.StorageComponent; + +/** RTT promotion. */ +public final class RttPromotion implements Promotion { + private static final String SHARED_PREFERENCE_KEY_ENABLED = "rtt_promotion_enabled"; + private static final String SHARED_PREFERENCE_KEY_DISMISSED = "rtt_promotion_dismissed"; + private final Context appContext; + + public RttPromotion(Context context) { + appContext = context.getApplicationContext(); + } + + @Override + public boolean shouldShow() { + SharedPreferences sharedPreferences = StorageComponent.get(appContext).unencryptedSharedPrefs(); + return sharedPreferences.getBoolean(SHARED_PREFERENCE_KEY_ENABLED, false) + && !sharedPreferences.getBoolean(SHARED_PREFERENCE_KEY_DISMISSED, false); + } + + @Override + public CharSequence getTitle() { + return appContext.getString(R.string.rtt_promotion_title); + } + + @Override + public CharSequence getDetails() { + return new ContentWithLearnMoreSpanner(appContext) + .create( + appContext.getString(R.string.rtt_promotion_details), + ConfigProviderBindings.get(appContext) + .getString( + "rtt_promo_learn_more_link_full_url", + "http://support.google.com/pixelphone/?p=dialer_rtt")); + } + + @Override + @DrawableRes + public int getIconRes() { + return R.drawable.quantum_ic_rtt_vd_theme_24; + } + + @Override + public void setShouldShow(boolean shouldShow) { + LogUtil.i("RttPromotion.setShouldShow", "shouldShow: %b", shouldShow); + StorageComponent.get(appContext) + .unencryptedSharedPrefs() + .edit() + .putBoolean(SHARED_PREFERENCE_KEY_ENABLED, shouldShow) + .apply(); + } + + @Override + public void dismiss() { + StorageComponent.get(appContext) + .unencryptedSharedPrefs() + .edit() + .putBoolean(SHARED_PREFERENCE_KEY_DISMISSED, true) + .apply(); + } +} diff --git a/java/com/android/dialer/promotion/res/values/strings.xml b/java/com/android/dialer/promotion/res/values/strings.xml new file mode 100644 index 000000000..633671546 --- /dev/null +++ b/java/com/android/dialer/promotion/res/values/strings.xml @@ -0,0 +1,26 @@ +<?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 + --> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <!-- Title for RTT promotion dialog. [CHAR LIMIT=NONE] --> + <string name="rtt_promotion_title">Real-time text messaging within a call</string> + + <!-- Details for RTT promotion dialog. [CHAR LIMIT=NONE] --> + <string name="rtt_promotion_details">RTT assists callers who are deaf, hard of hearing, have a speech + disability, or need more than voice alone. RTT messaging transcripts are stored on your device + in the call history. <xliff:g exmaple="Learn More">%1$s</xliff:g></string> + +</resources> diff --git a/java/com/android/dialer/simulator/impl/SimulatorModule.java b/java/com/android/dialer/simulator/impl/SimulatorModule.java index 2bc72c956..af554b66f 100644 --- a/java/com/android/dialer/simulator/impl/SimulatorModule.java +++ b/java/com/android/dialer/simulator/impl/SimulatorModule.java @@ -16,6 +16,8 @@ package com.android.dialer.simulator.impl; +import com.android.dialer.inject.DialerVariant; +import com.android.dialer.inject.InstallIn; import com.android.dialer.simulator.Simulator; import com.android.dialer.simulator.SimulatorConnectionsBank; import dagger.Binds; @@ -23,6 +25,7 @@ import dagger.Module; import javax.inject.Singleton; /** This module provides an instance of the simulator. */ +@InstallIn(variants = {DialerVariant.DIALER_TEST}) @Module public abstract class SimulatorModule { @Binds diff --git a/java/com/android/dialer/simulator/stub/StubSimulatorEnrichedCallModule.java b/java/com/android/dialer/simulator/stub/StubSimulatorEnrichedCallModule.java index 36314e7a9..6a002f0e1 100644 --- a/java/com/android/dialer/simulator/stub/StubSimulatorEnrichedCallModule.java +++ b/java/com/android/dialer/simulator/stub/StubSimulatorEnrichedCallModule.java @@ -16,12 +16,15 @@ package com.android.dialer.simulator.stub; +import com.android.dialer.inject.DialerVariant; +import com.android.dialer.inject.InstallIn; import com.android.dialer.simulator.SimulatorEnrichedCall; import dagger.Binds; import dagger.Module; import javax.inject.Singleton; /** Provides a stub instance of SimulatorEnrichedCall. */ +@InstallIn(variants = {DialerVariant.DIALER_TEST}) @Module public abstract class StubSimulatorEnrichedCallModule { @Binds diff --git a/java/com/android/dialer/spam/status/SimpleSpamStatus.java b/java/com/android/dialer/spam/status/SimpleSpamStatus.java index ec28b9dce..ff080ed1d 100644 --- a/java/com/android/dialer/spam/status/SimpleSpamStatus.java +++ b/java/com/android/dialer/spam/status/SimpleSpamStatus.java @@ -33,4 +33,10 @@ public abstract class SimpleSpamStatus implements SpamStatus { public static SimpleSpamStatus notSpam() { return create(false, null); } + + /** Returns an empty {@link SpamMetadata}. */ + @Override + public final SpamMetadata getSpamMetadata() { + return SpamMetadata.empty(); + } } diff --git a/java/com/android/dialer/spam/status/SpamMetadata.java b/java/com/android/dialer/spam/status/SpamMetadata.java new file mode 100644 index 000000000..40feba1a7 --- /dev/null +++ b/java/com/android/dialer/spam/status/SpamMetadata.java @@ -0,0 +1,52 @@ +/* + * 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.spam.status; + +import com.google.auto.value.AutoValue; +import com.google.common.base.Optional; + +/** + * Holds information which can be used to determine a number's spam status. + * + * @see SpamStatus + */ +@AutoValue +public abstract class SpamMetadata { + + /** Returns an empty spam metadata, no optional data is set. */ + public static SpamMetadata empty() { + return builder().build(); + } + + public static SpamMetadata.Builder builder() { + return new AutoValue_SpamMetadata.Builder(); + } + + public abstract Optional<GlobalSpamListStatus> globalSpamListStatus(); + + public abstract Optional<UserSpamListStatus> userSpamListStatus(); + + /** Creates instances of SpamMetadata. */ + @AutoValue.Builder + public abstract static class Builder { + public abstract Builder setGlobalSpamListStatus(GlobalSpamListStatus globalSpamListStatus); + + public abstract Builder setUserSpamListStatus(UserSpamListStatus userSpamListStatus); + + public abstract SpamMetadata build(); + } +} diff --git a/java/com/android/dialer/spam/status/SpamStatus.java b/java/com/android/dialer/spam/status/SpamStatus.java index 8186ac5cc..10e8213ab 100644 --- a/java/com/android/dialer/spam/status/SpamStatus.java +++ b/java/com/android/dialer/spam/status/SpamStatus.java @@ -37,4 +37,7 @@ public interface SpamStatus { * </ul> */ Optional<Long> getTimestampMillis(); + + /** Returns the {@link SpamMetadata} associated with this status. */ + SpamMetadata getSpamMetadata(); } diff --git a/java/com/android/dialer/strictmode/impl/SystemStrictModeModule.java b/java/com/android/dialer/strictmode/impl/SystemStrictModeModule.java index 6ece874fe..ac6416cfc 100644 --- a/java/com/android/dialer/strictmode/impl/SystemStrictModeModule.java +++ b/java/com/android/dialer/strictmode/impl/SystemStrictModeModule.java @@ -16,12 +16,15 @@ package com.android.dialer.strictmode.impl; +import com.android.dialer.inject.DialerVariant; +import com.android.dialer.inject.InstallIn; import com.android.dialer.strictmode.DialerStrictMode; import dagger.Binds; import dagger.Module; import javax.inject.Singleton; /** Module which binds {@link SystemDialerStrictMode}. */ +@InstallIn(variants = {DialerVariant.DIALER_TEST}) @Module public abstract class SystemStrictModeModule { diff --git a/java/com/android/incallui/AnswerScreenPresenter.java b/java/com/android/incallui/AnswerScreenPresenter.java index e41bac606..8b789f317 100644 --- a/java/com/android/incallui/AnswerScreenPresenter.java +++ b/java/com/android/incallui/AnswerScreenPresenter.java @@ -176,9 +176,6 @@ public class AnswerScreenPresenter return; } incomingCall.setIsSpeakEasyCall(true); - InCallActivity inCallActivity = - (InCallActivity) answerScreen.getAnswerScreenFragment().getActivity(); - inCallActivity.onPrimaryCallStateChanged(); } @Override diff --git a/java/com/android/incallui/InCallActivity.java b/java/com/android/incallui/InCallActivity.java index 98f001925..70ba71ba1 100644 --- a/java/com/android/incallui/InCallActivity.java +++ b/java/com/android/incallui/InCallActivity.java @@ -1247,13 +1247,13 @@ public class InCallActivity extends TransactionSafeFragmentActivity ShouldShowUiResult shouldShowSpeakEasyUi = getShouldShowSpeakEasyUi(); LogUtil.i( "InCallActivity.showMainInCallFragment", - "shouldShowAnswerUi: %b, shouldShowRttUi: %b, shouldShowVideoUi: %b " - + "didShowAnswerScreen: %b, didShowInCallScreen: %b, didShowRttCallScreen: %b, " - + "didShowVideoCallScreen: %b" - + "didShowSpeakEasyScreen: %b", + "shouldShowAnswerUi: %b, shouldShowRttUi: %b, shouldShowVideoUi: %b, " + + "shouldShowSpeakEasyUi: %b, didShowAnswerScreen: %b, didShowInCallScreen: %b, " + + "didShowRttCallScreen: %b, didShowVideoCallScreen: %b, didShowSpeakEasyScreen: %b", shouldShowAnswerUi.shouldShow, shouldShowRttUi.shouldShow, shouldShowVideoUi.shouldShow, + shouldShowSpeakEasyUi.shouldShow, didShowAnswerScreen, didShowInCallScreen, didShowRttCallScreen, diff --git a/java/com/android/incallui/InCallPresenter.java b/java/com/android/incallui/InCallPresenter.java index ccc564806..da5d20fa3 100644 --- a/java/com/android/incallui/InCallPresenter.java +++ b/java/com/android/incallui/InCallPresenter.java @@ -990,6 +990,13 @@ public class InCallPresenter implements CallList.Listener, AudioModeProvider.Aud } @Override + public void onSpeakEasyStateChange() { + if (inCallActivity != null) { + inCallActivity.onPrimaryCallStateChanged(); + } + } + + @Override public void onSessionModificationStateChange(DialerCall call) { int newState = call.getVideoTech().getSessionModificationState(); LogUtil.i("InCallPresenter.onSessionModificationStateChange", "state: %d", newState); diff --git a/java/com/android/incallui/call/CallList.java b/java/com/android/incallui/call/CallList.java index 0e89ac75d..13be252dd 100644 --- a/java/com/android/incallui/call/CallList.java +++ b/java/com/android/incallui/call/CallList.java @@ -39,6 +39,7 @@ import com.android.dialer.logging.DialerImpression; import com.android.dialer.logging.Logger; import com.android.dialer.metrics.Metrics; import com.android.dialer.metrics.MetricsComponent; +import com.android.dialer.promotion.RttPromotion; import com.android.dialer.shortcuts.ShortcutUsageReporter; import com.android.dialer.spam.Spam; import com.android.dialer.spam.SpamComponent; @@ -226,6 +227,9 @@ public class CallList implements DialerCallDelegate { if (call.getState() == DialerCallState.INCOMING || call.getState() == DialerCallState.CALL_WAITING) { if (call.isActiveRttCall()) { + if (!call.isPhoneAccountRttCapable()) { + new RttPromotion(context).setShouldShow(true); + } Logger.get(context) .logCallImpression( DialerImpression.Type.INCOMING_RTT_CALL, @@ -816,6 +820,9 @@ public class CallList implements DialerCallDelegate { */ default void onUpgradeToRtt(DialerCall call, int rttRequestId) {} + /** Called when the SpeakEasy state of a Dialer call is mutated. */ + default void onSpeakEasyStateChange() {} + /** Called when the session modification state of a call changes. */ void onSessionModificationStateChange(DialerCall call); @@ -894,6 +901,13 @@ public class CallList implements DialerCallDelegate { } @Override + public void onDialerCallSpeakEasyStateChange() { + for (Listener listener : listeners) { + listener.onSpeakEasyStateChange(); + } + } + + @Override public void onDialerCallUpgradeToVideo() { for (Listener listener : listeners) { listener.onUpgradeToVideo(call); diff --git a/java/com/android/incallui/call/DialerCall.java b/java/com/android/incallui/call/DialerCall.java index 77e2ea30b..431634a0c 100644 --- a/java/com/android/incallui/call/DialerCall.java +++ b/java/com/android/incallui/call/DialerCall.java @@ -1067,7 +1067,7 @@ public class DialerCall implements VideoTechListener, StateChangedListener, Capa } @TargetApi(28) - public boolean canUpgradeToRttCall() { + public boolean isPhoneAccountRttCapable() { PhoneAccount phoneAccount = getPhoneAccount(); if (phoneAccount == null) { return false; @@ -1075,6 +1075,14 @@ public class DialerCall implements VideoTechListener, StateChangedListener, Capa if (!phoneAccount.hasCapabilities(PhoneAccount.CAPABILITY_RTT)) { return false; } + return true; + } + + @TargetApi(28) + public boolean canUpgradeToRttCall() { + if (!isPhoneAccountRttCapable()) { + return false; + } if (isActiveRttCall()) { return false; } @@ -1718,6 +1726,11 @@ public class DialerCall implements VideoTechListener, StateChangedListener, Capa /** Sets the user preference for SpeakEasy */ public void setIsSpeakEasyCall(boolean isSpeakEasyCall) { this.isSpeakEasyCall = isSpeakEasyCall; + if (listeners != null) { + for (DialerCallListener listener : listeners) { + listener.onDialerCallSpeakEasyStateChange(); + } + } } /** diff --git a/java/com/android/incallui/call/DialerCallListener.java b/java/com/android/incallui/call/DialerCallListener.java index 37c30d30c..a42ccbd66 100644 --- a/java/com/android/incallui/call/DialerCallListener.java +++ b/java/com/android/incallui/call/DialerCallListener.java @@ -31,6 +31,8 @@ public interface DialerCallListener { default void onDialerCallUpgradeToRtt(int rttRequestId) {} + default void onDialerCallSpeakEasyStateChange() {} + void onDialerCallSessionModificationStateChange(); void onWiFiToLteHandover(); diff --git a/java/com/android/incallui/calllocation/stub/StubCallLocationModule.java b/java/com/android/incallui/calllocation/stub/StubCallLocationModule.java index 20460699a..c60663bff 100644 --- a/java/com/android/incallui/calllocation/stub/StubCallLocationModule.java +++ b/java/com/android/incallui/calllocation/stub/StubCallLocationModule.java @@ -20,12 +20,15 @@ import android.content.Context; import android.support.annotation.NonNull; import android.support.v4.app.Fragment; import com.android.dialer.common.Assert; +import com.android.dialer.inject.DialerVariant; +import com.android.dialer.inject.InstallIn; import com.android.incallui.calllocation.CallLocation; import dagger.Binds; import dagger.Module; import javax.inject.Inject; /** This module provides an instance of call location. */ +@InstallIn(variants = {DialerVariant.DIALER_TEST}) @Module public abstract class StubCallLocationModule { diff --git a/java/com/android/incallui/speakeasy/StubSpeakEasyModule.java b/java/com/android/incallui/speakeasy/StubSpeakEasyModule.java index 960692b20..d5f644372 100644 --- a/java/com/android/incallui/speakeasy/StubSpeakEasyModule.java +++ b/java/com/android/incallui/speakeasy/StubSpeakEasyModule.java @@ -17,12 +17,15 @@ package com.android.incallui.speakeasy; import android.support.v4.app.Fragment; +import com.android.dialer.inject.DialerVariant; +import com.android.dialer.inject.InstallIn; import com.google.common.base.Optional; import dagger.Binds; import dagger.Module; import dagger.Provides; /** Module which binds {@link SpeakEasyCallManagerStub}. */ +@InstallIn(variants = {DialerVariant.DIALER_TEST}) @Module public abstract class StubSpeakEasyModule { diff --git a/java/com/android/voicemail/impl/VoicemailModule.java b/java/com/android/voicemail/impl/VoicemailModule.java index e689e47d2..c4c72d30c 100644 --- a/java/com/android/voicemail/impl/VoicemailModule.java +++ b/java/com/android/voicemail/impl/VoicemailModule.java @@ -19,6 +19,8 @@ package com.android.voicemail.impl; import android.content.Context; import android.support.v4.os.BuildCompat; import com.android.dialer.inject.ApplicationContext; +import com.android.dialer.inject.DialerVariant; +import com.android.dialer.inject.InstallIn; import com.android.voicemail.VoicemailClient; import com.android.voicemail.VoicemailPermissionHelper; import com.android.voicemail.stub.StubVoicemailClient; @@ -27,6 +29,7 @@ import dagger.Provides; import javax.inject.Singleton; /** This module provides an instance of the voicemail client. */ +@InstallIn(variants = {DialerVariant.DIALER_TEST}) @Module public final class VoicemailModule { |