summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/com/android/dialer/DialtactsActivity.java46
-rw-r--r--src/com/android/dialer/calllog/CallLogAdapter.java13
-rw-r--r--src/com/android/dialer/calllog/CallLogFragment.java95
-rw-r--r--src/com/android/dialer/calllog/DefaultVoicemailNotifier.java6
-rw-r--r--src/com/android/dialer/dialpad/DialpadFragment.java13
-rw-r--r--src/com/android/dialer/list/AllContactsFragment.java90
-rw-r--r--src/com/android/dialer/list/EmptyContactsListAdapter.java47
-rw-r--r--src/com/android/dialer/list/RegularSearchFragment.java49
-rw-r--r--src/com/android/dialer/list/SearchFragment.java18
-rw-r--r--src/com/android/dialer/list/SmartDialSearchFragment.java52
-rw-r--r--src/com/android/dialer/list/SpeedDialFragment.java50
-rw-r--r--src/com/android/dialer/util/DialerUtils.java22
-rw-r--r--src/com/android/dialer/voicemail/VoicemailPlaybackLayout.java2
-rw-r--r--src/com/android/dialer/voicemail/VoicemailPlaybackPresenter.java24
-rw-r--r--src/com/android/dialer/widget/EmptyContentView.java117
15 files changed, 526 insertions, 118 deletions
diff --git a/src/com/android/dialer/DialtactsActivity.java b/src/com/android/dialer/DialtactsActivity.java
index 31d1b94bf..98f34b57d 100644
--- a/src/com/android/dialer/DialtactsActivity.java
+++ b/src/com/android/dialer/DialtactsActivity.java
@@ -66,6 +66,7 @@ import com.android.contacts.common.util.PermissionsUtil;
import com.android.contacts.common.widget.FloatingActionButtonController;
import com.android.contacts.commonbind.analytics.AnalyticsUtil;
import com.android.dialer.calllog.CallLogActivity;
+import com.android.dialer.calllog.CallLogFragment;
import com.android.dialer.database.DialerDatabaseHelper;
import com.android.dialer.dialpad.DialpadFragment;
import com.android.dialer.dialpad.SmartDialNameMatcher;
@@ -101,6 +102,8 @@ import java.util.List;
public class DialtactsActivity extends TransactionSafeActivity implements View.OnClickListener,
DialpadFragment.OnDialpadQueryChangedListener,
OnListFragmentScrolledListener,
+ CallLogFragment.HostInterface,
+ DialpadFragment.HostInterface,
ListsFragment.HostInterface,
SpeedDialFragment.HostInterface,
SearchFragment.HostInterface,
@@ -484,8 +487,6 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O
}
});
- setupActivityOverlay();
-
Trace.endSection();
Trace.beginSection(TAG + " initialize smart dialing");
@@ -495,19 +496,6 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O
Trace.endSection();
}
- private void setupActivityOverlay() {
- final View activityOverlay = findViewById(R.id.activity_overlay);
- activityOverlay.setOnTouchListener(new OnTouchListener() {
- @Override
- public boolean onTouch(View v, MotionEvent event) {
- if (!mIsDialpadShown) {
- maybeExitSearchUi();
- }
- return false;
- }
- });
- }
-
@Override
protected void onResume() {
Trace.beginSection(TAG + " onResume");
@@ -1145,7 +1133,16 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O
} catch (Exception ignored) {
// Skip any exceptions for this piece of code
}
+ }
+ @Override
+ public boolean onDialpadSpacerTouchWithEmptyQuery() {
+ if (mInDialpadSearch && mSmartDialSearchFragment != null
+ && !mSmartDialSearchFragment.isShowingPermissionRequest()) {
+ hideDialpadFragment(true /* animate */, true /* clearDialpad */);
+ return true;
+ }
+ return false;
}
@Override
@@ -1207,6 +1204,24 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O
mListsFragment.getRemoveView().setDragDropController(dragController);
}
+ /**
+ * Implemented to satisfy {@link SpeedDialFragment.HostInterface}
+ */
+ @Override
+ public void showAllContactsTab() {
+ if (mListsFragment != null) {
+ mListsFragment.showTab(ListsFragment.TAB_INDEX_ALL_CONTACTS);
+ }
+ }
+
+ /**
+ * Implemented to satisfy {@link CallLogFragment.HostInterface}
+ */
+ @Override
+ public void showDialpad() {
+ showDialpadFragment(true);
+ }
+
@Override
public void onPickPhoneNumberAction(Uri dataUri) {
// Specify call-origin so that users will see the previous tab instead of
@@ -1322,7 +1337,6 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O
return mActionBarHeight;
}
-
private int getFabAlignment() {
if (!mIsLandscape && !isInSearchUi() &&
mListsFragment.getCurrentTabIndex() == ListsFragment.TAB_INDEX_SPEED_DIAL) {
diff --git a/src/com/android/dialer/calllog/CallLogAdapter.java b/src/com/android/dialer/calllog/CallLogAdapter.java
index 00e9ea016..9609e4d6f 100644
--- a/src/com/android/dialer/calllog/CallLogAdapter.java
+++ b/src/com/android/dialer/calllog/CallLogAdapter.java
@@ -65,7 +65,9 @@ import java.util.HashMap;
* Adapter class to fill in data for the Call Log.
*/
public class CallLogAdapter extends GroupingListAdapter
- implements ViewTreeObserver.OnPreDrawListener, CallLogGroupBuilder.GroupCreator {
+ implements ViewTreeObserver.OnPreDrawListener,
+ CallLogGroupBuilder.GroupCreator,
+ VoicemailPlaybackPresenter.OnVoicemailDeletedListener {
/** Interface used to initiate a refresh of the content. */
public interface CallFetcher {
@@ -314,6 +316,9 @@ public class CallLogAdapter extends GroupingListAdapter
mCallFetcher = callFetcher;
mContactInfoHelper = contactInfoHelper;
mVoicemailPlaybackPresenter = voicemailPlaybackPresenter;
+ if (mVoicemailPlaybackPresenter != null) {
+ mVoicemailPlaybackPresenter.setOnVoicemailDeletedListener(this);
+ }
mIsShowingRecentsTab = isShowingRecentsTab;
mContactInfoCache = new ContactInfoCache(
@@ -619,6 +624,12 @@ public class CallLogAdapter extends GroupingListAdapter
return mIsShowingRecentsTab;
}
+ @Override
+ public void onVoicemailDeleted(Uri uri) {
+ mCurrentlyExpandedRowId = NO_EXPANDED_LIST_ITEM;
+ mCurrentlyExpandedPosition = RecyclerView.NO_POSITION;
+ }
+
/**
* Retrieves the day group of the previous call in the call log. Used to determine if the day
* group has changed and to trigger display of the day group text.
diff --git a/src/com/android/dialer/calllog/CallLogFragment.java b/src/com/android/dialer/calllog/CallLogFragment.java
index 5d7c408ce..59e2c7f38 100644
--- a/src/com/android/dialer/calllog/CallLogFragment.java
+++ b/src/com/android/dialer/calllog/CallLogFragment.java
@@ -16,6 +16,8 @@
package com.android.dialer.calllog;
+import static android.Manifest.permission.READ_CALL_LOG;
+
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
@@ -26,6 +28,7 @@ import android.app.KeyguardManager;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.PackageManager;
import android.database.ContentObserver;
import android.database.Cursor;
import android.graphics.Rect;
@@ -46,6 +49,7 @@ import android.widget.ListView;
import android.widget.TextView;
import com.android.contacts.common.GeoUtil;
+import com.android.contacts.common.util.PermissionsUtil;
import com.android.contacts.common.util.ViewUtil;
import com.android.dialer.R;
import com.android.dialer.list.ListsFragment.HostInterface;
@@ -55,6 +59,8 @@ import com.android.dialer.voicemail.VoicemailPlaybackPresenter;
import com.android.dialer.voicemail.VoicemailStatusHelper;
import com.android.dialer.voicemail.VoicemailStatusHelper.StatusMessage;
import com.android.dialer.voicemail.VoicemailStatusHelperImpl;
+import com.android.dialer.widget.EmptyContentView;
+import com.android.dialer.widget.EmptyContentView.OnEmptyViewActionButtonClickedListener;
import com.android.dialerbind.ObjectFactory;
import java.util.List;
@@ -63,8 +69,8 @@ import java.util.List;
* Displays a list of call log entries. To filter for a particular kind of call
* (all, missed or voicemails), specify it in the constructor.
*/
-public class CallLogFragment extends Fragment
- implements CallLogQueryHandler.Listener, CallLogAdapter.CallFetcher {
+public class CallLogFragment extends Fragment implements CallLogQueryHandler.Listener,
+ CallLogAdapter.CallFetcher, OnEmptyViewActionButtonClickedListener {
private static final String TAG = "CallLogFragment";
/**
@@ -81,6 +87,8 @@ public class CallLogFragment extends Fragment
// No date-based filtering.
private static final int NO_DATE_LIMIT = 0;
+ private static final int READ_CALL_LOG_PERMISSION_REQUEST_CODE = 1;
+
private RecyclerView mRecyclerView;
private LinearLayoutManager mLayoutManager;
private CallLogAdapter mAdapter;
@@ -91,7 +99,7 @@ public class CallLogFragment extends Fragment
/** Whether there is at least one voicemail source installed. */
private boolean mVoicemailSourcesAvailable = false;
- private View mEmptyListView;
+ private EmptyContentView mEmptyListView;
private KeyguardManager mKeyguardManager;
private boolean mEmptyLoaderRunning;
@@ -116,6 +124,8 @@ public class CallLogFragment extends Fragment
private final ContentObserver mVoicemailStatusObserver = new CustomContentObserver();
private boolean mRefreshDataRequired = true;
+ private boolean mHasReadCallLogPermission = false;
+
// Exactly same variable is in Fragment as a package private.
private boolean mMenuVisible = true;
@@ -130,6 +140,16 @@ public class CallLogFragment extends Fragment
// the date filter are included. If zero, no date-based filtering occurs.
private long mDateLimit = NO_DATE_LIMIT;
+ /*
+ * True if this instance of the CallLogFragment is the Recents screen shown in
+ * DialtactsActivity.
+ */
+ private boolean mIsRecentsFragment;
+
+ public interface HostInterface {
+ public void showDialpad();
+ }
+
public CallLogFragment() {
this(CallLogQueryHandler.CALL_TYPE_ALL, NO_LOG_LIMIT);
}
@@ -139,9 +159,7 @@ public class CallLogFragment extends Fragment
}
public CallLogFragment(int filterType, int logLimit) {
- super();
- mCallTypeFilter = filterType;
- mLogLimit = logLimit;
+ this(filterType, logLimit, NO_DATE_LIMIT);
}
/**
@@ -162,7 +180,8 @@ public class CallLogFragment extends Fragment
* @param dateLimit limits results to calls occurring on or after the specified date.
*/
public CallLogFragment(int filterType, int logLimit, long dateLimit) {
- this(filterType, logLimit);
+ mCallTypeFilter = filterType;
+ mLogLimit = logLimit;
mDateLimit = dateLimit;
}
@@ -175,6 +194,8 @@ public class CallLogFragment extends Fragment
mDateLimit = state.getLong(KEY_DATE_LIMIT, mDateLimit);
}
+ mIsRecentsFragment = mLogLimit != NO_LOG_LIMIT;
+
final Activity activity = getActivity();
final ContentResolver resolver = activity.getContentResolver();
String currentCountryIso = GeoUtil.getCurrentCountryIso(activity);
@@ -268,7 +289,9 @@ public class CallLogFragment extends Fragment
mRecyclerView.setHasFixedSize(true);
mLayoutManager = new LinearLayoutManager(getActivity());
mRecyclerView.setLayoutManager(mLayoutManager);
- mEmptyListView = view.findViewById(R.id.empty_list_view);
+ mEmptyListView = (EmptyContentView) view.findViewById(R.id.empty_list_view);
+ mEmptyListView.setImage(R.drawable.empty_call_log);
+ mEmptyListView.setActionClickedListener(this);
String currentCountryIso = GeoUtil.getCurrentCountryIso(getActivity());
boolean isShowingRecentsTab = mLogLimit != NO_LOG_LIMIT || mDateLimit != NO_DATE_LIMIT;
@@ -287,7 +310,6 @@ public class CallLogFragment extends Fragment
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
-
updateEmptyMessage(mCallTypeFilter);
mAdapter.onRestoreInstanceState(savedInstanceState);
}
@@ -305,6 +327,16 @@ public class CallLogFragment extends Fragment
@Override
public void onResume() {
super.onResume();
+ final boolean hasReadCallLogPermission =
+ PermissionsUtil.hasPermission(getActivity(), READ_CALL_LOG);
+ if (!mHasReadCallLogPermission && hasReadCallLogPermission) {
+ // We didn't have the permission before, and now we do. Force a refresh of the call log.
+ // Note that this code path always happens on a fresh start, but mRefreshDataRequired
+ // is already true in that case anyway.
+ mRefreshDataRequired = true;
+ updateEmptyMessage(mCallTypeFilter);
+ }
+ mHasReadCallLogPermission = hasReadCallLogPermission;
refreshData();
}
@@ -359,6 +391,17 @@ public class CallLogFragment extends Fragment
}
private void updateEmptyMessage(int filterType) {
+ final Context context = getActivity();
+ if (context == null) {
+ return;
+ }
+
+ if (!PermissionsUtil.hasPermission(context, READ_CALL_LOG)) {
+ mEmptyListView.setDescription(R.string.permission_no_calllog);
+ mEmptyListView.setActionLabel(R.string.permission_single_turn_on);
+ return;
+ }
+
final int messageId;
switch (filterType) {
case Calls.MISSED_TYPE:
@@ -374,8 +417,12 @@ public class CallLogFragment extends Fragment
throw new IllegalArgumentException("Unexpected filter type in CallLogFragment: "
+ filterType);
}
- DialerUtils.configureEmptyListView(
- mEmptyListView, R.drawable.empty_call_log, messageId, getResources());
+ mEmptyListView.setDescription(messageId);
+ if (mIsRecentsFragment) {
+ mEmptyListView.setActionLabel(R.string.recentCalls_empty_action);
+ } else {
+ mEmptyListView.setActionLabel(EmptyContentView.NO_LABEL);
+ }
}
CallLogAdapter getAdapter() {
@@ -437,4 +484,30 @@ public class CallLogFragment extends Fragment
CallLogNotificationsHelper.updateVoicemailNotifications(getActivity());
}
}
+
+ @Override
+ public void onEmptyViewActionButtonClicked() {
+ final Activity activity = getActivity();
+ if (activity == null) {
+ return;
+ }
+
+ if (!PermissionsUtil.hasPermission(activity, READ_CALL_LOG)) {
+ requestPermissions(new String[] {READ_CALL_LOG}, READ_CALL_LOG_PERMISSION_REQUEST_CODE);
+ } else if (mIsRecentsFragment) {
+ // Show dialpad if we are the recents fragment.
+ ((HostInterface) activity).showDialpad();
+ }
+ }
+
+ @Override
+ public void onRequestPermissionsResult(int requestCode, String[] permissions,
+ int[] grantResults) {
+ if (requestCode == READ_CALL_LOG_PERMISSION_REQUEST_CODE) {
+ if (grantResults.length >= 1 && PackageManager.PERMISSION_GRANTED == grantResults[0]) {
+ // Force a refresh of the data since we were missing the permission before this.
+ mRefreshDataRequired = true;
+ }
+ }
+ }
}
diff --git a/src/com/android/dialer/calllog/DefaultVoicemailNotifier.java b/src/com/android/dialer/calllog/DefaultVoicemailNotifier.java
index d0553b4ac..a6d165e3a 100644
--- a/src/com/android/dialer/calllog/DefaultVoicemailNotifier.java
+++ b/src/com/android/dialer/calllog/DefaultVoicemailNotifier.java
@@ -302,6 +302,9 @@ public class DefaultVoicemailNotifier {
newCalls[cursor.getPosition()] = createNewCallsFromCursor(cursor);
}
return newCalls;
+ } catch (RuntimeException e) {
+ Log.w(TAG, "Exception when querying Contacts Provider for calls lookup");
+ return null;
} finally {
MoreCloseables.closeQuietly(cursor);
}
@@ -371,6 +374,9 @@ public class DefaultVoicemailNotifier {
PROJECTION, null, null, null);
if (cursor == null || !cursor.moveToFirst()) return null;
return cursor.getString(DISPLAY_NAME_COLUMN_INDEX);
+ } catch (RuntimeException e) {
+ Log.w(TAG, "Exception when querying Contacts Provider for name lookup");
+ return null;
} finally {
if (cursor != null) {
cursor.close();
diff --git a/src/com/android/dialer/dialpad/DialpadFragment.java b/src/com/android/dialer/dialpad/DialpadFragment.java
index b18069fdd..d35abd75b 100644
--- a/src/com/android/dialer/dialpad/DialpadFragment.java
+++ b/src/com/android/dialer/dialpad/DialpadFragment.java
@@ -135,6 +135,15 @@ public class DialpadFragment extends Fragment
void onDialpadQueryChanged(String query);
}
+ public interface HostInterface {
+ /**
+ * Notifies the parent activity that the space above the dialpad has been tapped with
+ * no query in the dialpad present. In most situations this will cause the dialpad to
+ * be dismissed, unless there happens to be content showing.
+ */
+ boolean onDialpadSpacerTouchWithEmptyQuery();
+ }
+
private static final boolean DEBUG = DialtactsActivity.DEBUG;
// This is the amount of screen the dialpad fragment takes up when fully displayed
@@ -385,7 +394,9 @@ public class DialpadFragment extends Fragment
@Override
public boolean onTouch(View v, MotionEvent event) {
if (isDigitsEmpty()) {
- hideAndClearDialpad(true);
+ if (getActivity() != null) {
+ return ((HostInterface) getActivity()).onDialpadSpacerTouchWithEmptyQuery();
+ }
return true;
}
return false;
diff --git a/src/com/android/dialer/list/AllContactsFragment.java b/src/com/android/dialer/list/AllContactsFragment.java
index d34250b48..0f31ff88f 100644
--- a/src/com/android/dialer/list/AllContactsFragment.java
+++ b/src/com/android/dialer/list/AllContactsFragment.java
@@ -16,7 +16,14 @@
package com.android.dialer.list;
+import static android.Manifest.permission.READ_CONTACTS;
+
+import android.app.Activity;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
import android.content.Loader;
+import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.provider.ContactsContract.CommonDataKinds.Phone;
@@ -34,13 +41,30 @@ import com.android.contacts.common.util.PermissionsUtil;
import com.android.contacts.common.util.ViewUtil;
import com.android.dialer.R;
import com.android.dialer.util.DialerUtils;
+import com.android.dialer.util.IntentUtil;
+import com.android.dialer.widget.EmptyContentView;
+import com.android.dialer.widget.EmptyContentView.OnEmptyViewActionButtonClickedListener;
/**
* Fragments to show all contacts with phone numbers.
*/
-public class AllContactsFragment extends ContactEntryListFragment<ContactEntryListAdapter> {
+public class AllContactsFragment extends ContactEntryListFragment<ContactEntryListAdapter>
+ implements OnEmptyViewActionButtonClickedListener {
+
+ private static final int READ_CONTACTS_PERMISSION_REQUEST_CODE = 1;
+
+ private EmptyContentView mEmptyListView;
- private View mEmptyListView;
+ /**
+ * 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 BroadcastReceiver mReadContactsPermissionGrantedReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ reloadData();
+ }
+ };
public AllContactsFragment() {
setQuickContactEnabled(false);
@@ -55,9 +79,10 @@ public class AllContactsFragment extends ContactEntryListFragment<ContactEntryLi
public void onViewCreated(View view, android.os.Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
- mEmptyListView = view.findViewById(R.id.empty_list_view);
- DialerUtils.configureEmptyListView(mEmptyListView, R.drawable.empty_contacts,
- R.string.all_contacts_empty, getResources());
+ mEmptyListView = (EmptyContentView) view.findViewById(R.id.empty_list_view);
+ mEmptyListView.setImage(R.drawable.empty_contacts);
+ mEmptyListView.setDescription(R.string.all_contacts_empty);
+ mEmptyListView.setActionClickedListener(this);
getListView().setEmptyView(mEmptyListView);
mEmptyListView.setVisibility(View.GONE);
@@ -65,9 +90,29 @@ public class AllContactsFragment extends ContactEntryListFragment<ContactEntryLi
}
@Override
+ public void onStart() {
+ super.onStart();
+ PermissionsUtil.registerPermissionReceiver(getActivity(),
+ mReadContactsPermissionGrantedReceiver, READ_CONTACTS);
+ }
+
+ @Override
+ public void onStop() {
+ PermissionsUtil.unregisterPermissionReceiver(getActivity(),
+ mReadContactsPermissionGrantedReceiver);
+ super.onStop();
+ }
+
+ @Override
protected void startLoading() {
- if (PermissionsUtil.hasContactsPermissions(getActivity())) {
+ if (PermissionsUtil.hasPermission(getActivity(), READ_CONTACTS)) {
super.startLoading();
+ mEmptyListView.setDescription(R.string.all_contacts_empty);
+ mEmptyListView.setActionLabel(R.string.all_contacts_empty_add_contact_action);
+ } else {
+ mEmptyListView.setDescription(R.string.permission_no_contacts);
+ mEmptyListView.setActionLabel(R.string.permission_single_turn_on);
+ mEmptyListView.setVisibility(View.VISIBLE);
}
}
@@ -82,10 +127,6 @@ public class AllContactsFragment extends ContactEntryListFragment<ContactEntryLi
@Override
protected ContactEntryListAdapter createListAdapter() {
- if (!PermissionsUtil.hasContactsPermissions(getActivity())) {
- return new EmptyContactsListAdapter(getActivity());
- }
-
final DefaultContactListAdapter adapter = new DefaultContactListAdapter(getActivity()) {
@Override
protected void bindView(View itemView, int partition, Cursor cursor, int position) {
@@ -102,7 +143,7 @@ public class AllContactsFragment extends ContactEntryListFragment<ContactEntryLi
@Override
protected View inflateView(LayoutInflater inflater, ViewGroup container) {
- return inflater.inflate(R.layout.show_all_contacts_fragment, null);
+ return inflater.inflate(R.layout.all_contacts_fragment, null);
}
@Override
@@ -118,4 +159,31 @@ public class AllContactsFragment extends ContactEntryListFragment<ContactEntryLi
protected void onItemClick(int position, long id) {
// Do nothing. Implemented to satisfy ContactEntryListFragment.
}
+
+ @Override
+ public void onEmptyViewActionButtonClicked() {
+ final Activity activity = getActivity();
+ if (activity == null) {
+ return;
+ }
+
+ if (!PermissionsUtil.hasPermission(activity, READ_CONTACTS)) {
+ requestPermissions(new String[] {READ_CONTACTS}, READ_CONTACTS_PERMISSION_REQUEST_CODE);
+ } else {
+ // Add new contact
+ DialerUtils.startActivityWithErrorToast(activity, IntentUtil.getNewContactIntent(),
+ R.string.add_contact_not_available);
+ }
+ }
+
+ @Override
+ public void onRequestPermissionsResult(int requestCode, String[] permissions,
+ int[] grantResults) {
+ if (requestCode == READ_CONTACTS_PERMISSION_REQUEST_CODE) {
+ if (grantResults.length >= 1 && PackageManager.PERMISSION_GRANTED == grantResults[0]) {
+ // Force a refresh of the data since we were missing the permission before this.
+ reloadData();
+ }
+ }
+ }
}
diff --git a/src/com/android/dialer/list/EmptyContactsListAdapter.java b/src/com/android/dialer/list/EmptyContactsListAdapter.java
deleted file mode 100644
index 54bd4771f..000000000
--- a/src/com/android/dialer/list/EmptyContactsListAdapter.java
+++ /dev/null
@@ -1,47 +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.dialer.list;
-
-import android.content.Context;
-import android.content.CursorLoader;
-
-import com.android.contacts.common.list.ContactEntryListAdapter;
-
-/**
- * Used to display an empty contact list when we don't have the permissions to read contacts.
- */
-public class EmptyContactsListAdapter extends ContactEntryListAdapter {
-
- public EmptyContactsListAdapter(Context context) {
- super(context);
- }
-
- @Override
- public String getContactDisplayName(int position) {
- return null;
- }
-
- @Override
- public void configureLoader(CursorLoader loader, long directoryId) {
- loader.setUri(null);
- }
-
- @Override
- public int getCount() {
- return 0;
- }
-}
diff --git a/src/com/android/dialer/list/RegularSearchFragment.java b/src/com/android/dialer/list/RegularSearchFragment.java
index 19c7321a1..b7e26d690 100644
--- a/src/com/android/dialer/list/RegularSearchFragment.java
+++ b/src/com/android/dialer/list/RegularSearchFragment.java
@@ -15,16 +15,29 @@
*/
package com.android.dialer.list;
+import static android.Manifest.permission.ACCESS_FINE_LOCATION;
+import static android.Manifest.permission.READ_CONTACTS;
+
+import android.app.Activity;
+import android.content.pm.PackageManager;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import com.android.contacts.common.list.ContactEntryListAdapter;
import com.android.contacts.common.list.PinnedHeaderListView;
+import com.android.contacts.common.util.PermissionsUtil;
import com.android.contacts.commonbind.analytics.AnalyticsUtil;
import com.android.dialerbind.ObjectFactory;
+
+import com.android.dialer.R;
import com.android.dialer.service.CachedNumberLookupService;
+import com.android.dialer.widget.EmptyContentView;
+import com.android.dialer.widget.EmptyContentView.OnEmptyViewActionButtonClickedListener;
-public class RegularSearchFragment extends SearchFragment {
+public class RegularSearchFragment extends SearchFragment
+ implements OnEmptyViewActionButtonClickedListener {
+
+ private static final int READ_CONTACTS_PERMISSION_REQUEST_CODE = 1;
private static final int SEARCH_DIRECTORY_RESULT_LIMIT = 5;
@@ -68,4 +81,38 @@ public class RegularSearchFragment extends SearchFragment {
adapter.getContactInfo(mCachedNumberLookupService, position));
}
}
+
+ @Override
+ protected void setupEmptyView() {
+ if (mEmptyView != null && getActivity() != null) {
+ if (!PermissionsUtil.hasPermission(getActivity(), READ_CONTACTS)) {
+ mEmptyView.setImage(R.drawable.empty_contacts);
+ mEmptyView.setActionLabel(R.string.permission_single_turn_on);
+ mEmptyView.setDescription(R.string.permission_no_search);
+ mEmptyView.setActionClickedListener(this);
+ } else {
+ mEmptyView.setImage(EmptyContentView.NO_IMAGE);
+ mEmptyView.setActionLabel(EmptyContentView.NO_LABEL);
+ mEmptyView.setDescription(EmptyContentView.NO_LABEL);
+ }
+ }
+ }
+
+ @Override
+ public void onEmptyViewActionButtonClicked() {
+ final Activity activity = getActivity();
+ if (activity == null) {
+ return;
+ }
+
+ requestPermissions(new String[] {READ_CONTACTS}, READ_CONTACTS_PERMISSION_REQUEST_CODE);
+ }
+
+ @Override
+ public void onRequestPermissionsResult(int requestCode, String[] permissions,
+ int[] grantResults) {
+ if (requestCode == READ_CONTACTS_PERMISSION_REQUEST_CODE) {
+ setupEmptyView();
+ }
+ }
}
diff --git a/src/com/android/dialer/list/SearchFragment.java b/src/com/android/dialer/list/SearchFragment.java
index 77ab29198..315cfb914 100644
--- a/src/com/android/dialer/list/SearchFragment.java
+++ b/src/com/android/dialer/list/SearchFragment.java
@@ -15,6 +15,8 @@
*/
package com.android.dialer.list;
+import static android.Manifest.permission.READ_CONTACTS;
+
import android.animation.Animator;
import android.animation.AnimatorInflater;
import android.animation.AnimatorListenerAdapter;
@@ -50,6 +52,7 @@ import com.android.dialer.dialpad.DialpadFragment.ErrorDialogFragment;
import com.android.dialer.R;
import com.android.dialer.util.DialerUtils;
import com.android.dialer.util.IntentUtil;
+import com.android.dialer.widget.EmptyContentView;
import com.android.phone.common.animation.AnimUtils;
public class SearchFragment extends PhoneNumberPickerFragment {
@@ -79,6 +82,8 @@ public class SearchFragment extends PhoneNumberPickerFragment {
private HostInterface mActivity;
+ protected EmptyContentView mEmptyView;
+
public interface HostInterface {
public boolean isActionBarShowing();
public boolean isDialpadShown();
@@ -125,6 +130,13 @@ public class SearchFragment extends PhoneNumberPickerFragment {
final ListView listView = getListView();
+ if (mEmptyView == null) {
+ mEmptyView = new EmptyContentView(getActivity());
+ ((ViewGroup) getListView().getParent()).addView(mEmptyView);
+ getListView().setEmptyView(mEmptyView);
+ setupEmptyView();
+ }
+
listView.setBackgroundColor(res.getColor(R.color.background_dialer_results));
listView.setClipToPadding(false);
setVisibleScrollbarEnabled(false);
@@ -341,7 +353,7 @@ public class SearchFragment extends PhoneNumberPickerFragment {
@Override
protected void startLoading() {
- if (PermissionsUtil.hasContactsPermissions(getActivity())) {
+ if (PermissionsUtil.hasPermission(getActivity(), READ_CONTACTS)) {
super.startLoading();
} else if (TextUtils.isEmpty(getQueryString())) {
// Clear out any existing call shortcuts.
@@ -354,6 +366,8 @@ public class SearchFragment extends PhoneNumberPickerFragment {
// list.
getAdapter().notifyDataSetChanged();
}
+
+ setupEmptyView();
}
public void setOnTouchListener(View.OnTouchListener onTouchListener) {
@@ -371,4 +385,6 @@ public class SearchFragment extends PhoneNumberPickerFragment {
}
return parent;
}
+
+ protected void setupEmptyView() {}
}
diff --git a/src/com/android/dialer/list/SmartDialSearchFragment.java b/src/com/android/dialer/list/SmartDialSearchFragment.java
index 082bc4360..72d3abf68 100644
--- a/src/com/android/dialer/list/SmartDialSearchFragment.java
+++ b/src/com/android/dialer/list/SmartDialSearchFragment.java
@@ -15,21 +15,33 @@
*/
package com.android.dialer.list;
+import static android.Manifest.permission.CALL_PHONE;
+
+import android.app.Activity;
import android.content.Loader;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
+import android.view.View;
import com.android.contacts.common.list.ContactEntryListAdapter;
+import com.android.contacts.common.util.PermissionsUtil;
import com.android.dialer.dialpad.SmartDialCursorLoader;
+import com.android.dialer.R;
+import com.android.dialer.widget.EmptyContentView;
+
+import java.util.ArrayList;
/**
* Implements a fragment to load and display SmartDial search results.
*/
-public class SmartDialSearchFragment extends SearchFragment {
+public class SmartDialSearchFragment extends SearchFragment
+ implements EmptyContentView.OnEmptyViewActionButtonClickedListener {
private static final String TAG = SmartDialSearchFragment.class.getSimpleName();
+ private static final int CALL_PHONE_PERMISSION_REQUEST_CODE = 1;
+
/**
* Creates a SmartDialListAdapter to display and operate on search results.
*/
@@ -69,4 +81,42 @@ public class SmartDialSearchFragment extends SearchFragment {
final SmartDialNumberListAdapter adapter = (SmartDialNumberListAdapter) getAdapter();
return adapter.getDataUri(position);
}
+
+ @Override
+ protected void setupEmptyView() {
+ if (mEmptyView != null && getActivity() != null) {
+ if (!PermissionsUtil.hasPermission(getActivity(), CALL_PHONE)) {
+ mEmptyView.setImage(R.drawable.empty_contacts);
+ mEmptyView.setActionLabel(R.string.permission_single_turn_on);
+ mEmptyView.setDescription(R.string.permission_place_call);
+ mEmptyView.setActionClickedListener(this);
+ } else {
+ mEmptyView.setImage(EmptyContentView.NO_IMAGE);
+ mEmptyView.setActionLabel(EmptyContentView.NO_LABEL);
+ mEmptyView.setDescription(EmptyContentView.NO_LABEL);
+ }
+ }
+ }
+
+ @Override
+ public void onEmptyViewActionButtonClicked() {
+ final Activity activity = getActivity();
+ if (activity == null) {
+ return;
+ }
+
+ requestPermissions(new String[] {CALL_PHONE}, CALL_PHONE_PERMISSION_REQUEST_CODE);
+ }
+
+ @Override
+ public void onRequestPermissionsResult(int requestCode, String[] permissions,
+ int[] grantResults) {
+ if (requestCode == CALL_PHONE_PERMISSION_REQUEST_CODE) {
+ setupEmptyView();
+ }
+ }
+
+ public boolean isShowingPermissionRequest() {
+ return mEmptyView != null && mEmptyView.isShowingContent();
+ }
}
diff --git a/src/com/android/dialer/list/SpeedDialFragment.java b/src/com/android/dialer/list/SpeedDialFragment.java
index bf9575858..324caefb6 100644
--- a/src/com/android/dialer/list/SpeedDialFragment.java
+++ b/src/com/android/dialer/list/SpeedDialFragment.java
@@ -15,6 +15,8 @@
*/
package com.android.dialer.list;
+import static android.Manifest.permission.READ_CONTACTS;
+
import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
@@ -23,6 +25,7 @@ import android.app.Fragment;
import android.app.LoaderManager;
import android.content.CursorLoader;
import android.content.Loader;
+import android.content.pm.PackageManager;
import android.database.Cursor;
import android.graphics.Rect;
import android.net.Uri;
@@ -50,6 +53,7 @@ import com.android.contacts.common.list.OnPhoneNumberPickerActionListener;
import com.android.contacts.common.util.PermissionsUtil;
import com.android.dialer.R;
import com.android.dialer.util.DialerUtils;
+import com.android.dialer.widget.EmptyContentView;
import java.util.ArrayList;
import java.util.HashMap;
@@ -58,7 +62,10 @@ import java.util.HashMap;
* This fragment displays the user's favorite/frequent contacts in a grid.
*/
public class SpeedDialFragment extends Fragment implements OnItemClickListener,
- PhoneFavoritesTileAdapter.OnDataSetChangedForAnimationListener {
+ PhoneFavoritesTileAdapter.OnDataSetChangedForAnimationListener,
+ EmptyContentView.OnEmptyViewActionButtonClickedListener {
+
+ private static final int READ_CONTACTS_PERMISSION_REQUEST_CODE = 1;
/**
* By default, the animation code assumes that all items in a list view are of the same height
@@ -81,6 +88,7 @@ public class SpeedDialFragment extends Fragment implements OnItemClickListener,
public interface HostInterface {
public void setDragDropController(DragDropController controller);
+ public void showAllContactsTab();
}
private class ContactTileLoaderListener implements LoaderManager.LoaderCallbacks<Cursor> {
@@ -157,7 +165,7 @@ public class SpeedDialFragment extends Fragment implements OnItemClickListener,
/**
* Layout used when there are no favorites.
*/
- private View mEmptyView;
+ private EmptyContentView mEmptyView;
private final ContactTileView.Listener mContactTileAdapterListener =
new ContactTileAdapterListener();
@@ -197,9 +205,16 @@ public class SpeedDialFragment extends Fragment implements OnItemClickListener,
if (getLoaderManager().getLoader(LOADER_ID_CONTACT_TILE) == null) {
getLoaderManager().initLoader(LOADER_ID_CONTACT_TILE, null,
mContactTileLoaderListener);
+
} else {
getLoaderManager().getLoader(LOADER_ID_CONTACT_TILE).forceLoad();
}
+
+ mEmptyView.setDescription(R.string.speed_dial_empty);
+ mEmptyView.setActionLabel(R.string.speed_dial_empty_add_favorite_action);
+ } else {
+ mEmptyView.setDescription(R.string.permission_no_speeddial);
+ mEmptyView.setActionLabel(R.string.permission_single_turn_on);
}
Trace.endSection();
}
@@ -221,9 +236,9 @@ public class SpeedDialFragment extends Fragment implements OnItemClickListener,
(ImageView) getActivity().findViewById(R.id.contact_tile_drag_shadow_overlay);
mListView.setDragShadowOverlay(dragShadowOverlay);
- mEmptyView = mParentView.findViewById(R.id.empty_list_view);
- DialerUtils.configureEmptyListView(
- mEmptyView, R.drawable.empty_speed_dial, R.string.speed_dial_empty, getResources());
+ mEmptyView = (EmptyContentView) mParentView.findViewById(R.id.empty_list_view);
+ mEmptyView.setImage(R.drawable.empty_speed_dial);
+ mEmptyView.setActionClickedListener(this);
mContactTileFrame = mParentView.findViewById(R.id.contact_tile_frame);
@@ -449,4 +464,29 @@ public class SpeedDialFragment extends Fragment implements OnItemClickListener,
public AbsListView getListView() {
return mListView;
}
+
+ @Override
+ public void onEmptyViewActionButtonClicked() {
+ final Activity activity = getActivity();
+ if (activity == null) {
+ return;
+ }
+
+ if (!PermissionsUtil.hasPermission(activity, READ_CONTACTS)) {
+ requestPermissions(new String[] {READ_CONTACTS}, READ_CONTACTS_PERMISSION_REQUEST_CODE);
+ } else {
+ // Switch tabs
+ ((HostInterface) activity).showAllContactsTab();
+ }
+ }
+
+ @Override
+ public void onRequestPermissionsResult(int requestCode, String[] permissions,
+ int[] grantResults) {
+ if (requestCode == READ_CONTACTS_PERMISSION_REQUEST_CODE) {
+ if (grantResults.length == 1 && PackageManager.PERMISSION_GRANTED == grantResults[0]) {
+ PermissionsUtil.notifyPermissionGranted(getActivity(), READ_CONTACTS);
+ }
+ }
+ }
}
diff --git a/src/com/android/dialer/util/DialerUtils.java b/src/com/android/dialer/util/DialerUtils.java
index a44c2eec6..e25ada59d 100644
--- a/src/com/android/dialer/util/DialerUtils.java
+++ b/src/com/android/dialer/util/DialerUtils.java
@@ -40,6 +40,7 @@ import android.widget.Toast;
import com.android.contacts.common.ContactsUtils;
import com.android.contacts.common.interactions.TouchPointManager;
import com.android.dialer.R;
+import com.android.dialer.widget.EmptyContentView;
import com.android.incallui.CallCardFragment;
import com.android.incallui.Log;
@@ -116,27 +117,6 @@ public class DialerUtils {
}
/**
- * Sets the image asset and text for an empty list view (see empty_list_view.xml).
- *
- * @param emptyListView The empty list view.
- * @param imageResId The resource id for the drawable to set as the image.
- * @param strResId The resource id for the string to set as the message.
- * @param res The resources to obtain the image and string from.
- */
- public static void configureEmptyListView(
- View emptyListView, int imageResId, int strResId, Resources res) {
- ImageView emptyListViewImage =
- (ImageView) emptyListView.findViewById(R.id.emptyListViewImage);
-
- emptyListViewImage.setImageDrawable(res.getDrawable(imageResId));
- emptyListViewImage.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
-
- TextView emptyListViewMessage =
- (TextView) emptyListView.findViewById(R.id.emptyListViewMessage);
- emptyListViewMessage.setText(res.getString(strResId));
- }
-
- /**
* Closes an {@link AutoCloseable}, silently ignoring any checked exceptions. Does nothing if
* null.
*
diff --git a/src/com/android/dialer/voicemail/VoicemailPlaybackLayout.java b/src/com/android/dialer/voicemail/VoicemailPlaybackLayout.java
index 2017bc578..213bba164 100644
--- a/src/com/android/dialer/voicemail/VoicemailPlaybackLayout.java
+++ b/src/com/android/dialer/voicemail/VoicemailPlaybackLayout.java
@@ -183,7 +183,9 @@ public class VoicemailPlaybackLayout extends LinearLayout
if (mPresenter == null) {
return;
}
+ mPresenter.pausePlayback();
CallLogAsyncTaskUtil.deleteVoicemail(mContext, mVoicemailUri, null);
+ mPresenter.onVoicemailDeleted();
}
};
diff --git a/src/com/android/dialer/voicemail/VoicemailPlaybackPresenter.java b/src/com/android/dialer/voicemail/VoicemailPlaybackPresenter.java
index fb9e3edfb..7270af787 100644
--- a/src/com/android/dialer/voicemail/VoicemailPlaybackPresenter.java
+++ b/src/com/android/dialer/voicemail/VoicemailPlaybackPresenter.java
@@ -92,6 +92,10 @@ public class VoicemailPlaybackPresenter
void setPresenter(VoicemailPlaybackPresenter presenter, Uri voicemailUri);
}
+ public interface OnVoicemailDeletedListener {
+ void onVoicemailDeleted(Uri uri);
+ }
+
/** The enumeration of {@link AsyncTask} objects we use in this class. */
public enum Tasks {
CHECK_FOR_CONTENT,
@@ -155,6 +159,8 @@ public class VoicemailPlaybackPresenter
private PowerManager.WakeLock mProximityWakeLock;
private AudioManager mAudioManager;
+ private OnVoicemailDeletedListener mOnVoicemailDeletedListener;
+
/**
* Obtain singleton instance of this class. Use a single instance to provide a consistent
* listener to the AudioManager when requesting and abandoning audio focus.
@@ -634,7 +640,8 @@ public class VoicemailPlaybackPresenter
mMediaPlayer.pause();
}
- mPosition = mMediaPlayer.getCurrentPosition();
+ mPosition = mMediaPlayer == null ? 0 : mMediaPlayer.getCurrentPosition();
+
Log.d(TAG, "Paused playback at " + mPosition + ".");
if (mView != null) {
@@ -653,7 +660,9 @@ public class VoicemailPlaybackPresenter
* playing to know whether to resume playback once the user selects a new position.
*/
public void pausePlaybackForSeeking() {
- mShouldResumePlaybackAfterSeeking = mMediaPlayer.isPlaying();
+ if (mMediaPlayer != null) {
+ mShouldResumePlaybackAfterSeeking = mMediaPlayer.isPlaying();
+ }
pausePlayback();
}
@@ -712,10 +721,21 @@ public class VoicemailPlaybackPresenter
return mAudioManager.isSpeakerphoneOn();
}
+ public void setOnVoicemailDeletedListener(OnVoicemailDeletedListener listener) {
+ mOnVoicemailDeletedListener = listener;
+ }
+
public int getMediaPlayerPosition() {
return mIsPrepared && mMediaPlayer != null ? mMediaPlayer.getCurrentPosition() : 0;
}
+ /* package */ void onVoicemailDeleted() {
+ // Trampoline the event notification to the interested listener
+ if (mOnVoicemailDeletedListener != null) {
+ mOnVoicemailDeletedListener.onVoicemailDeleted(mVoicemailUri);
+ }
+ }
+
private static synchronized ScheduledExecutorService getScheduledExecutorServiceInstance() {
if (mScheduledExecutorService == null) {
mScheduledExecutorService = Executors.newScheduledThreadPool(NUMBER_OF_THREADS_IN_POOL);
diff --git a/src/com/android/dialer/widget/EmptyContentView.java b/src/com/android/dialer/widget/EmptyContentView.java
new file mode 100644
index 000000000..f248967de
--- /dev/null
+++ b/src/com/android/dialer/widget/EmptyContentView.java
@@ -0,0 +1,117 @@
+/*
+ * 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.dialer.widget;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.android.dialer.R;
+
+public class EmptyContentView extends LinearLayout implements View.OnClickListener {
+
+ public static final int NO_LABEL = 0;
+ public static final int NO_IMAGE = 0;
+
+ private ImageView mImageView;
+ private TextView mDescriptionView;
+ private TextView mActionView;
+ private OnEmptyViewActionButtonClickedListener mOnActionButtonClickedListener;
+
+ public interface OnEmptyViewActionButtonClickedListener {
+ public void onEmptyViewActionButtonClicked();
+ }
+
+ public EmptyContentView(Context context) {
+ this(context, null);
+ }
+
+ public EmptyContentView(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public EmptyContentView(Context context, AttributeSet attrs, int defStyleAttr) {
+ this(context, attrs, defStyleAttr, 0);
+ }
+
+ public EmptyContentView(Context context, AttributeSet attrs, int defStyleAttr,
+ int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ setOrientation(LinearLayout.VERTICAL);
+
+ final LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(
+ Context.LAYOUT_INFLATER_SERVICE);
+ inflater.inflate(R.layout.empty_content_view, this);
+ // Don't let touches fall through the empty view.
+ setClickable(true);
+ mImageView = (ImageView) findViewById(R.id.emptyListViewImage);
+ mDescriptionView = (TextView) findViewById(R.id.emptyListViewMessage);
+ mActionView = (TextView) findViewById(R.id.emptyListViewAction);
+ mActionView.setOnClickListener(this);
+ }
+
+ public void setDescription(int resourceId) {
+ if (resourceId == NO_LABEL) {
+ mDescriptionView.setText(null);
+ mDescriptionView.setVisibility(View.GONE);
+ } else {
+ mDescriptionView.setText(resourceId);
+ mDescriptionView.setVisibility(View.VISIBLE);
+ }
+ }
+
+ public void setImage(int resourceId) {
+ mImageView.setImageResource(resourceId);
+ if (resourceId == NO_LABEL) {
+ mImageView.setVisibility(View.GONE);
+ } else {
+ mImageView.setVisibility(View.VISIBLE);
+ }
+ }
+
+ public void setActionLabel(int resourceId) {
+ if (resourceId == NO_LABEL) {
+ mActionView.setText(null);
+ mActionView.setVisibility(View.GONE);
+ } else {
+ mActionView.setText(resourceId);
+ mActionView.setVisibility(View.VISIBLE);
+ }
+ }
+
+ public boolean isShowingContent() {
+ return mImageView.getVisibility() == View.VISIBLE
+ || mDescriptionView.getVisibility() == View.VISIBLE
+ || mActionView.getVisibility() == View.VISIBLE;
+ }
+
+ public void setActionClickedListener(OnEmptyViewActionButtonClickedListener listener) {
+ mOnActionButtonClickedListener = listener;
+ }
+
+ @Override
+ public void onClick(View v) {
+ if (mOnActionButtonClickedListener != null) {
+ mOnActionButtonClickedListener.onEmptyViewActionButtonClicked();
+ }
+ }
+}