From 5f420e2b26f0da3fea065c62d3bf6d347cacbe25 Mon Sep 17 00:00:00 2001 From: Hadrien De Sousa <hadrien.desousa@savoirfairelinux.com> Date: Wed, 17 May 2017 16:37:25 -0400 Subject: [PATCH] mvp: refactor ProfileCreationFragment Apply MVP to ProfileCreationFragment Tuleap: #1369 Change-Id: Id4434fb1d663d001350a7c0da51340da284d23a3 Reviewed-by: Aline Bonnet <aline.bonnet@savoirfairelinux.com> --- .../ProfileCreationFragment.java | 128 ++++++++++-------- .../account/ProfileCreationPresenter.java | 82 +++++++++++ .../cx/ring/account/ProfileCreationView.java | 39 ++++++ .../java/cx/ring/client/AccountWizard.java | 22 +-- .../RingInjectionComponent.java | 2 +- .../services/DeviceRuntimeServiceImpl.java | 18 +++ .../ring/services/DeviceRuntimeService.java | 2 + 7 files changed, 218 insertions(+), 75 deletions(-) rename ring-android/app/src/main/java/cx/ring/{fragments => account}/ProfileCreationFragment.java (66%) create mode 100644 ring-android/app/src/main/java/cx/ring/account/ProfileCreationPresenter.java create mode 100644 ring-android/app/src/main/java/cx/ring/account/ProfileCreationView.java diff --git a/ring-android/app/src/main/java/cx/ring/fragments/ProfileCreationFragment.java b/ring-android/app/src/main/java/cx/ring/account/ProfileCreationFragment.java similarity index 66% rename from ring-android/app/src/main/java/cx/ring/fragments/ProfileCreationFragment.java rename to ring-android/app/src/main/java/cx/ring/account/ProfileCreationFragment.java index a99d06b14..1993372a6 100644 --- a/ring-android/app/src/main/java/cx/ring/fragments/ProfileCreationFragment.java +++ b/ring-android/app/src/main/java/cx/ring/account/ProfileCreationFragment.java @@ -18,10 +18,10 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -package cx.ring.fragments; +package cx.ring.account; import android.Manifest; -import android.app.Fragment; +import android.app.Activity; import android.content.Intent; import android.database.Cursor; import android.graphics.Bitmap; @@ -51,12 +51,12 @@ import cx.ring.R; import cx.ring.adapters.ContactDetailsTask; import cx.ring.application.RingApplication; import cx.ring.client.AccountWizard; +import cx.ring.mvp.BaseFragment; import cx.ring.services.DeviceRuntimeService; import cx.ring.utils.BitmapUtils; -public class ProfileCreationFragment extends Fragment { +public class ProfileCreationFragment extends BaseFragment<ProfileCreationPresenter> implements ProfileCreationView { static final String TAG = ProfileCreationFragment.class.getSimpleName(); - private static final String[] PROFILE_PROJECTION = new String[]{ContactsContract.Profile._ID, ContactsContract.Profile.DISPLAY_NAME_PRIMARY, ContactsContract.Profile.PHOTO_ID}; public static final int REQUEST_CODE_PHOTO = 1; public static final int REQUEST_CODE_GALLERY = 2; public static final int REQUEST_PERMISSION_CAMERA = 3; @@ -64,31 +64,33 @@ public class ProfileCreationFragment extends Fragment { public static final String PHOTO_TAG = "Photo"; - @Inject - DeviceRuntimeService mDeviceRuntimeService; - @BindView(R.id.profile_photo) - ImageView mPhotoView; + protected ImageView mPhotoView; @BindView(R.id.user_name) - EditText mFullnameView; + protected EditText mFullnameView; @BindView(R.id.gallery) - ImageButton mGalleryButton; + protected ImageButton mGalleryButton; @BindView(R.id.camera) - ImageButton mCameraButton; + protected ImageButton mCameraButton; @BindView(R.id.next_create_account) - Button mNextButton; + protected Button mNextButton; @BindView(R.id.last_create_account) - Button mLastButton; + protected Button mLastButton; private Bitmap mSourcePhoto; @Override public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) { + final View view = inflater.inflate(R.layout.frag_acc_profile_create, parent, false); + ButterKnife.bind(this, view); + + // dependency injection + ((RingApplication) getActivity().getApplication()).getRingInjectionComponent().inject(this); if (savedInstanceState != null) { byte[] bytes = savedInstanceState.getByteArray(PHOTO_TAG); @@ -97,13 +99,7 @@ public class ProfileCreationFragment extends Fragment { } } - final View view = inflater.inflate(R.layout.frag_acc_profile_create, parent, false); - ButterKnife.bind(this, view); - - // dependency injection - ((RingApplication) getActivity().getApplication()).getRingInjectionComponent().inject(this); - - initProfile(); + presenter.initPresenter(); if (mPhotoView.getDrawable() == null) { if (mSourcePhoto == null) { mSourcePhoto = BitmapFactory.decodeResource(getActivity().getResources(), R.drawable.ic_contact_picture); @@ -123,19 +119,21 @@ public class ProfileCreationFragment extends Fragment { } } - private void initProfile() { - //~ Checking the state of the READ_CONTACTS permission - if (mDeviceRuntimeService.hasContactPermission()) { - Cursor mProfileCursor = getActivity().getContentResolver().query(ContactsContract.Profile.CONTENT_URI, PROFILE_PROJECTION, null, null, null); - if (mProfileCursor != null) { - if (mProfileCursor.moveToFirst()) { - String displayName = mProfileCursor.getString(mProfileCursor.getColumnIndex(ContactsContract.Profile.DISPLAY_NAME_PRIMARY)); - mFullnameView.setText(displayName); + @Override + public void onActivityResult(int requestCode, int resultCode, Intent data) { + switch (requestCode) { + case ProfileCreationFragment.REQUEST_CODE_PHOTO: + if (resultCode == Activity.RESULT_OK && data != null) { + updatePhoto((Bitmap) data.getExtras().get("data")); } - mProfileCursor.close(); - } - } else { - Log.d(TAG, "READ_CONTACTS permission is not granted."); + break; + case ProfileCreationFragment.REQUEST_CODE_GALLERY: + if (resultCode == Activity.RESULT_OK && data != null) { + updatePhoto(data.getData()); + } + break; + default: + break; } } @@ -150,39 +148,63 @@ public class ProfileCreationFragment extends Fragment { @OnClick(R.id.gallery) public void galleryClicked() { - boolean hasPermission = mDeviceRuntimeService.hasGalleryPermission(); - if (hasPermission) { - Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI); - getActivity().startActivityForResult(intent, REQUEST_CODE_GALLERY); - } else { - ActivityCompat.requestPermissions(getActivity(), - new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, - REQUEST_PERMISSION_READ_STORAGE); - } + presenter.galleryClick(); } @OnClick(R.id.camera) public void cameraClicked() { - boolean hasPermission = mDeviceRuntimeService.hasVideoPermission() && - mDeviceRuntimeService.hasPhotoPermission(); - if (hasPermission) { - Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); - getActivity().startActivityForResult(intent, REQUEST_CODE_PHOTO); - } else { - ActivityCompat.requestPermissions(getActivity(), - new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE}, - REQUEST_PERMISSION_CAMERA); - } + presenter.cameraClick(); } @OnClick(R.id.next_create_account) public void nextClicked() { - String fullname = mFullnameView.getText().toString().trim(); - ((AccountWizard) getActivity()).profileNext(fullname, mSourcePhoto); + presenter.nextClick(); } @OnClick(R.id.last_create_account) public void lastClicked() { + presenter.lastClick(); + } + + @Override + public void displayProfileName(String profileName) { + mFullnameView.setText(profileName); + } + + @Override + public void goToGallery() { + Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI); + startActivityForResult(intent, REQUEST_CODE_GALLERY); + } + + @Override + public void goToPhotoCapture() { + Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); + startActivityForResult(intent, REQUEST_CODE_PHOTO); + } + + @Override + public void askStoragePermission() { + ActivityCompat.requestPermissions(getActivity(), + new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, + REQUEST_PERMISSION_READ_STORAGE); + } + + @Override + public void askPhotoPermission() { + ActivityCompat.requestPermissions(getActivity(), + new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE}, + REQUEST_PERMISSION_CAMERA); + } + + @Override + public void goToNext() { + String fullname = mFullnameView.getText().toString().trim(); + ((AccountWizard) getActivity()).profileNext(fullname, mSourcePhoto); + } + + @Override + public void goToLast() { ((AccountWizard) getActivity()).profileLast(); } } diff --git a/ring-android/app/src/main/java/cx/ring/account/ProfileCreationPresenter.java b/ring-android/app/src/main/java/cx/ring/account/ProfileCreationPresenter.java new file mode 100644 index 000000000..3a2c860d6 --- /dev/null +++ b/ring-android/app/src/main/java/cx/ring/account/ProfileCreationPresenter.java @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2017 Savoir-faire Linux Inc. + * + * Author: Hadrien De Sousa <hadrien.desousa@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +package cx.ring.account; + +import javax.inject.Inject; + +import cx.ring.mvp.RootPresenter; +import cx.ring.services.DeviceRuntimeService; +import cx.ring.utils.Log; + +public class ProfileCreationPresenter extends RootPresenter<ProfileCreationView> { + + public static final String TAG = ProfileCreationPresenter.class.getSimpleName(); + + protected DeviceRuntimeService mDeviceRuntimeService; + + @Inject + public ProfileCreationPresenter(DeviceRuntimeService deviceRuntimeService) { + this.mDeviceRuntimeService = deviceRuntimeService; + } + + public void initPresenter() { + //~ Checking the state of the READ_CONTACTS permission + if (mDeviceRuntimeService.hasContactPermission()) { + String profileName = mDeviceRuntimeService.getProfileName(); + if (profileName != null) { + getView().displayProfileName(profileName); + } + } else { + Log.d(TAG, "READ_CONTACTS permission is not granted."); + } + } + + public void galleryClick() { + boolean hasPermission = mDeviceRuntimeService.hasGalleryPermission(); + if (hasPermission) { + getView().goToGallery(); + } else { + getView().askStoragePermission(); + } + } + + public void cameraClick() { + boolean hasPermission = mDeviceRuntimeService.hasVideoPermission() && + mDeviceRuntimeService.hasPhotoPermission(); + if (hasPermission) { + getView().goToPhotoCapture(); + } else { + getView().askPhotoPermission(); + } + } + + public void nextClick() { + getView().goToNext(); + } + + public void lastClick() { + getView().goToLast(); + } + + @Override + public void afterInjection() { + + } +} diff --git a/ring-android/app/src/main/java/cx/ring/account/ProfileCreationView.java b/ring-android/app/src/main/java/cx/ring/account/ProfileCreationView.java new file mode 100644 index 000000000..75043a338 --- /dev/null +++ b/ring-android/app/src/main/java/cx/ring/account/ProfileCreationView.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2017 Savoir-faire Linux Inc. + * + * Author: Hadrien De Sousa <hadrien.desousa@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +package cx.ring.account; + + +public interface ProfileCreationView { + + void displayProfileName(String profileName); + + void goToGallery(); + + void goToPhotoCapture(); + + void askStoragePermission(); + + void askPhotoPermission(); + + void goToNext(); + + void goToLast(); + +} diff --git a/ring-android/app/src/main/java/cx/ring/client/AccountWizard.java b/ring-android/app/src/main/java/cx/ring/client/AccountWizard.java index 51455e1f5..d278cbb13 100644 --- a/ring-android/app/src/main/java/cx/ring/client/AccountWizard.java +++ b/ring-android/app/src/main/java/cx/ring/client/AccountWizard.java @@ -54,7 +54,7 @@ import cx.ring.R; import cx.ring.application.RingApplication; import cx.ring.fragments.AccountMigrationFragment; import cx.ring.account.HomeAccountCreationFragment; -import cx.ring.fragments.ProfileCreationFragment; +import cx.ring.account.ProfileCreationFragment; import cx.ring.fragments.RingAccountCreationFragment; import cx.ring.fragments.RingLinkAccountFragment; import cx.ring.fragments.SIPAccountCreationFragment; @@ -509,26 +509,6 @@ public class AccountWizard extends AppCompatActivity implements Observer<Service new CreateAccountTask(this).execute(accountDetails); } - @Override - public void onActivityResult(int requestCode, int resultCode, Intent data) { - super.onActivityResult(requestCode, resultCode, data); - - switch (requestCode) { - case ProfileCreationFragment.REQUEST_CODE_PHOTO: - if (resultCode == RESULT_OK && data != null) { - mProfileFragment.updatePhoto((Bitmap) data.getExtras().get("data")); - } - break; - case ProfileCreationFragment.REQUEST_CODE_GALLERY: - if (resultCode == RESULT_OK && data != null) { - mProfileFragment.updatePhoto(data.getData()); - } - break; - default: - break; - } - } - private class WizardPagerAdapter extends FragmentStatePagerAdapter { WizardPagerAdapter(FragmentManager fm) { diff --git a/ring-android/app/src/main/java/cx/ring/dependencyinjection/RingInjectionComponent.java b/ring-android/app/src/main/java/cx/ring/dependencyinjection/RingInjectionComponent.java index 8a483bac8..005287480 100755 --- a/ring-android/app/src/main/java/cx/ring/dependencyinjection/RingInjectionComponent.java +++ b/ring-android/app/src/main/java/cx/ring/dependencyinjection/RingInjectionComponent.java @@ -41,7 +41,7 @@ import cx.ring.fragments.CallFragment; import cx.ring.fragments.ConversationFragment; import cx.ring.fragments.GeneralAccountFragment; import cx.ring.fragments.MediaPreferenceFragment; -import cx.ring.fragments.ProfileCreationFragment; +import cx.ring.account.ProfileCreationFragment; import cx.ring.fragments.RingAccountCreationFragment; import cx.ring.fragments.SIPAccountCreationFragment; import cx.ring.fragments.SecurityAccountFragment; diff --git a/ring-android/app/src/main/java/cx/ring/services/DeviceRuntimeServiceImpl.java b/ring-android/app/src/main/java/cx/ring/services/DeviceRuntimeServiceImpl.java index aeaeedf36..018e85120 100644 --- a/ring-android/app/src/main/java/cx/ring/services/DeviceRuntimeServiceImpl.java +++ b/ring-android/app/src/main/java/cx/ring/services/DeviceRuntimeServiceImpl.java @@ -22,10 +22,12 @@ package cx.ring.services; import android.Manifest; import android.content.Context; import android.content.pm.PackageManager; +import android.database.Cursor; import android.media.AudioManager; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.os.Handler; +import android.provider.ContactsContract; import android.support.v4.content.ContextCompat; import java.io.File; @@ -43,6 +45,9 @@ import cx.ring.utils.NetworkUtils; public class DeviceRuntimeServiceImpl extends DeviceRuntimeService { private static final String TAG = DeviceRuntimeServiceImpl.class.getName(); + private static final String[] PROFILE_PROJECTION = new String[]{ContactsContract.Profile._ID, + ContactsContract.Profile.DISPLAY_NAME_PRIMARY, + ContactsContract.Profile.PHOTO_ID}; @Inject @Named("DaemonExecutor") @@ -157,6 +162,19 @@ public class DeviceRuntimeServiceImpl extends DeviceRuntimeService { return checkPermission(Manifest.permission.READ_EXTERNAL_STORAGE); } + @Override + public String getProfileName() { + Cursor mProfileCursor = mContext.getContentResolver().query(ContactsContract.Profile.CONTENT_URI, PROFILE_PROJECTION, null, null, null); + if (mProfileCursor != null) { + if (mProfileCursor.moveToFirst()) { + mProfileCursor.close(); + return mProfileCursor.getString(mProfileCursor.getColumnIndex(ContactsContract.Profile.DISPLAY_NAME_PRIMARY)); + } + mProfileCursor.close(); + } + return null; + } + private boolean checkPermission(String permission) { return ContextCompat.checkSelfPermission(mContext, permission) == PackageManager.PERMISSION_GRANTED; } diff --git a/ring-android/libringclient/src/main/java/cx/ring/services/DeviceRuntimeService.java b/ring-android/libringclient/src/main/java/cx/ring/services/DeviceRuntimeService.java index b98b294d0..f21538b22 100644 --- a/ring-android/libringclient/src/main/java/cx/ring/services/DeviceRuntimeService.java +++ b/ring-android/libringclient/src/main/java/cx/ring/services/DeviceRuntimeService.java @@ -53,4 +53,6 @@ public abstract class DeviceRuntimeService { public abstract boolean hasGalleryPermission(); + public abstract String getProfileName(); + } -- GitLab