diff options
Diffstat (limited to 'java/com/android/dialer/speeddial')
4 files changed, 138 insertions, 17 deletions
diff --git a/java/com/android/dialer/speeddial/SpeedDialFragment.java b/java/com/android/dialer/speeddial/SpeedDialFragment.java index fac9a13d2..d9593c211 100644 --- a/java/com/android/dialer/speeddial/SpeedDialFragment.java +++ b/java/com/android/dialer/speeddial/SpeedDialFragment.java @@ -16,12 +16,16 @@ package com.android.dialer.speeddial; +import android.Manifest; +import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; +import android.content.pm.PackageManager; import android.net.Uri; import android.os.Bundle; import android.provider.ContactsContract.CommonDataKinds.Phone; import android.provider.ContactsContract.Contacts; +import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentActivity; @@ -35,6 +39,7 @@ import android.view.View; import android.view.ViewGroup; import com.android.dialer.callintent.CallInitiationType; import com.android.dialer.callintent.CallIntentBuilder; +import com.android.dialer.common.Assert; import com.android.dialer.common.FragmentUtils; import com.android.dialer.common.LogUtil; import com.android.dialer.common.concurrent.DefaultFutureCallback; @@ -59,9 +64,13 @@ import com.android.dialer.speeddial.draghelper.SpeedDialLayoutManager; import com.android.dialer.speeddial.loader.SpeedDialUiItem; import com.android.dialer.speeddial.loader.UiItemLoaderComponent; import com.android.dialer.util.IntentUtil; +import com.android.dialer.util.PermissionsUtil; +import com.android.dialer.widget.EmptyContentView; +import com.android.dialer.widget.EmptyContentView.OnEmptyViewActionButtonClickedListener; import com.google.common.collect.ImmutableList; import com.google.common.util.concurrent.Futures; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; /** @@ -76,6 +85,20 @@ import java.util.List; */ public class SpeedDialFragment extends Fragment { + private static final int READ_CONTACTS_PERMISSION_REQUEST_CODE = 1; + + /** + * Listen to broadcast events about permissions in order to be notified if the READ_CONTACTS + * permission is granted via the UI in another fragment. + */ + private final BroadcastReceiver readContactsPermissionGrantedReceiver = + new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + loadContacts(); + } + }; + private final SpeedDialHeaderListener headerListener = new SpeedDialFragmentHeaderListener(); private final SpeedDialSuggestedListener suggestedListener = new SpeedDialSuggestedListener(); @@ -83,6 +106,8 @@ public class SpeedDialFragment extends Fragment { private SupportUiListener<ImmutableList<SpeedDialUiItem>> speedDialLoaderListener; private SpeedDialFavoritesListener favoritesListener; + private EmptyContentView emptyContentView; + /** * We update the UI every time the fragment is resumed. This boolean suppresses that functionality * once per onResume call. @@ -99,6 +124,12 @@ public class SpeedDialFragment extends Fragment { LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { LogUtil.enterBlock("SpeedDialFragment.onCreateView"); View rootLayout = inflater.inflate(R.layout.fragment_speed_dial, container, false); + emptyContentView = rootLayout.findViewById(R.id.speed_dial_empty_content_view); + emptyContentView.setActionLabel(R.string.speed_dial_turn_on_contacts_permission); + emptyContentView.setDescription(R.string.speed_dial_contacts_permission_description); + emptyContentView.setImage(R.drawable.empty_speed_dial); + emptyContentView.setActionClickedListener( + new SpeedDialEmptyContentViewClickedListener(getContext(), this)); speedDialLoaderListener = DialerExecutorComponent.get(getContext()) @@ -132,11 +163,69 @@ public class SpeedDialFragment extends Fragment { @Override public void onResume() { super.onResume(); + loadContacts(); + } + + @Override + public void onPause() { + super.onPause(); + favoritesListener.hideMenu(); + suggestedListener.onPause(); + } + + @Override + public void onHiddenChanged(boolean hidden) { + super.onHiddenChanged(hidden); + if (hidden) { + onHidden(); + } else { + loadContacts(); + } + } + + private void onHidden() { + if (!PermissionsUtil.hasContactsReadPermissions(getContext())) { + return; + } + + Futures.addCallback( + DialerExecutorComponent.get(getContext()) + .backgroundExecutor() + .submit( + () -> { + UiItemLoaderComponent.get(getContext()) + .speedDialUiItemMutator() + .updatePinnedPosition(adapter.getSpeedDialUiItems()); + return null; + }), + new DefaultFutureCallback<>(), + DialerExecutorComponent.get(getContext()).backgroundExecutor()); + } + + @Override + public void onRequestPermissionsResult( + int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + if (requestCode == READ_CONTACTS_PERMISSION_REQUEST_CODE + && grantResults.length > 0 + && grantResults[0] == PackageManager.PERMISSION_GRANTED) { + PermissionsUtil.notifyPermissionGranted(getContext(), Manifest.permission.READ_CONTACTS); + loadContacts(); + } + } + + private void loadContacts() { if (!updateSpeedDialItemsOnResume) { updateSpeedDialItemsOnResume = true; return; } + if (!PermissionsUtil.hasContactsReadPermissions(getContext())) { + emptyContentView.setVisibility(View.VISIBLE); + return; + } else { + emptyContentView.setVisibility(View.GONE); + } + speedDialLoaderListener.listen( getContext(), UiItemLoaderComponent.get(getContext()).speedDialUiItemMutator().loadSpeedDialUiItems(), @@ -179,22 +268,17 @@ public class SpeedDialFragment extends Fragment { } @Override - public void onPause() { - super.onPause(); - favoritesListener.hideMenu(); - Futures.addCallback( - DialerExecutorComponent.get(getContext()) - .backgroundExecutor() - .submit( - () -> { - UiItemLoaderComponent.get(getContext()) - .speedDialUiItemMutator() - .updatePinnedPosition(adapter.getSpeedDialUiItems()); - return null; - }), - new DefaultFutureCallback<>(), - DialerExecutorComponent.get(getContext()).backgroundExecutor()); - suggestedListener.onPause(); + public void onStart() { + super.onStart(); + PermissionsUtil.registerPermissionReceiver( + getActivity(), readContactsPermissionGrantedReceiver, Manifest.permission.READ_CONTACTS); + } + + @Override + public void onStop() { + super.onStop(); + PermissionsUtil.unregisterPermissionReceiver( + getContext(), readContactsPermissionGrantedReceiver); } private class SpeedDialFragmentHeaderListener implements SpeedDialHeaderListener { @@ -455,6 +539,30 @@ public class SpeedDialFragment extends Fragment { } } + private static final class SpeedDialEmptyContentViewClickedListener + implements OnEmptyViewActionButtonClickedListener { + + private final Context context; + private final Fragment fragment; + + private SpeedDialEmptyContentViewClickedListener(Context context, Fragment fragment) { + this.context = context; + this.fragment = fragment; + } + + @Override + public void onEmptyViewActionButtonClicked() { + String[] deniedPermissions = + PermissionsUtil.getPermissionsCurrentlyDenied( + context, PermissionsUtil.allContactsGroupPermissionsUsedInDialer); + Assert.checkArgument(deniedPermissions.length > 0); + LogUtil.i( + "OldSpeedDialFragment.onEmptyViewActionButtonClicked", + "Requesting permissions: " + Arrays.toString(deniedPermissions)); + fragment.requestPermissions(deniedPermissions, READ_CONTACTS_PERMISSION_REQUEST_CODE); + } + } + /** Listener for when a SpeedDialUiItem is updated. */ private class UpdateSpeedDialAdapterListener { diff --git a/java/com/android/dialer/speeddial/database/SpeedDialEntryDatabaseHelper.java b/java/com/android/dialer/speeddial/database/SpeedDialEntryDatabaseHelper.java index 1416a203d..211af86ad 100644 --- a/java/com/android/dialer/speeddial/database/SpeedDialEntryDatabaseHelper.java +++ b/java/com/android/dialer/speeddial/database/SpeedDialEntryDatabaseHelper.java @@ -125,7 +125,7 @@ public final class SpeedDialEntryDatabaseHelper extends SQLiteOpenHelper Channel.builder() .setNumber(number) .setPhoneType(cursor.getInt(POSITION_PHONE_TYPE)) - .setLabel(cursor.getString(POSITION_PHONE_LABEL)) + .setLabel(Optional.of(cursor.getString(POSITION_PHONE_LABEL)).or("")) .setTechnology(cursor.getInt(POSITION_PHONE_TECHNOLOGY)) .build(); } diff --git a/java/com/android/dialer/speeddial/res/layout/fragment_speed_dial.xml b/java/com/android/dialer/speeddial/res/layout/fragment_speed_dial.xml index 9a42377be..1e35091c9 100644 --- a/java/com/android/dialer/speeddial/res/layout/fragment_speed_dial.xml +++ b/java/com/android/dialer/speeddial/res/layout/fragment_speed_dial.xml @@ -26,5 +26,12 @@ android:clipToPadding="false" android:background="@color/background_dialer_light" android:paddingBottom="@dimen/floating_action_button_list_bottom_padding"/> + + <com.android.dialer.widget.EmptyContentView + android:id="@+id/speed_dial_empty_content_view" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_gravity="center" + android:visibility="gone"/> </FrameLayout> diff --git a/java/com/android/dialer/speeddial/res/values/strings.xml b/java/com/android/dialer/speeddial/res/values/strings.xml index 0053074b2..7f11119c7 100644 --- a/java/com/android/dialer/speeddial/res/values/strings.xml +++ b/java/com/android/dialer/speeddial/res/values/strings.xml @@ -59,4 +59,10 @@ <!-- Text shown to the user in a button to prompt them to mark a contact as a favorite contact [CHAR LIMIT=30]. --> <string name="suggested_contact_bottom_sheet_add_favorite_option">Add favorite</string> + + <!-- Shown as a prompt to turn on the contacts permission to enable speed dial [CHAR LIMIT=NONE]--> + <string name="speed_dial_contacts_permission_description">To enable speed dial, turn on the Contacts permission.</string> + + <!-- The label of the button used to turn on a single permission [CHAR LIMIT=30]--> + <string name="speed_dial_turn_on_contacts_permission">Turn on</string> </resources>
\ No newline at end of file |