WelcomeActivity.java

  1package eu.siacs.conversations.ui;
  2
  3import android.Manifest;
  4import android.content.ActivityNotFoundException;
  5import android.content.Intent;
  6import android.content.pm.ActivityInfo;
  7import android.net.Uri;
  8import android.os.Bundle;
  9import android.security.KeyChain;
 10import android.security.KeyChainAliasCallback;
 11import android.util.Log;
 12import android.view.Menu;
 13import android.view.MenuItem;
 14import android.widget.Toast;
 15
 16import androidx.annotation.NonNull;
 17import androidx.appcompat.app.AppCompatActivity;
 18import androidx.databinding.DataBindingUtil;
 19
 20import java.util.Arrays;
 21import java.util.List;
 22
 23import eu.siacs.conversations.Config;
 24import eu.siacs.conversations.R;
 25import eu.siacs.conversations.databinding.ActivityWelcomeBinding;
 26import eu.siacs.conversations.entities.Account;
 27import eu.siacs.conversations.services.XmppConnectionService;
 28import eu.siacs.conversations.utils.Compatibility;
 29import eu.siacs.conversations.utils.InstallReferrerUtils;
 30import eu.siacs.conversations.utils.SignupUtils;
 31import eu.siacs.conversations.utils.XmppUri;
 32import eu.siacs.conversations.xmpp.Jid;
 33
 34import static eu.siacs.conversations.utils.PermissionUtils.allGranted;
 35import static eu.siacs.conversations.utils.PermissionUtils.writeGranted;
 36
 37public class WelcomeActivity extends XmppActivity implements XmppConnectionService.OnAccountCreated, KeyChainAliasCallback {
 38
 39    private static final int REQUEST_IMPORT_BACKUP = 0x63fb;
 40
 41    private XmppUri inviteUri;
 42
 43    public static void launch(AppCompatActivity activity) {
 44        Intent intent = new Intent(activity, WelcomeActivity.class);
 45        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
 46        activity.startActivity(intent);
 47        activity.overridePendingTransition(0, 0);
 48    }
 49
 50    public void onInstallReferrerDiscovered(final Uri referrer) {
 51        Log.d(Config.LOGTAG, "welcome activity: on install referrer discovered " + referrer);
 52        if ("xmpp".equalsIgnoreCase(referrer.getScheme())) {
 53            final XmppUri xmppUri = new XmppUri(referrer);
 54            runOnUiThread(() -> processXmppUri(xmppUri));
 55        } else {
 56            Log.i(Config.LOGTAG, "install referrer was not an XMPP uri");
 57        }
 58    }
 59
 60    private void processXmppUri(final XmppUri xmppUri) {
 61        if (!xmppUri.isValidJid()) {
 62            return;
 63        }
 64        final String preAuth = xmppUri.getParameter(XmppUri.PARAMETER_PRE_AUTH);
 65        final Jid jid = xmppUri.getJid();
 66        final Intent intent;
 67        if (xmppUri.isAction(XmppUri.ACTION_REGISTER)) {
 68            intent = SignupUtils.getTokenRegistrationIntent(this, jid, preAuth);
 69        } else if (xmppUri.isAction(XmppUri.ACTION_ROSTER) && "y".equals(xmppUri.getParameter(XmppUri.PARAMETER_IBR))) {
 70            intent = SignupUtils.getTokenRegistrationIntent(this, jid.getDomain(), preAuth);
 71            intent.putExtra(StartConversationActivity.EXTRA_INVITE_URI, xmppUri.toString());
 72        } else {
 73            intent = null;
 74        }
 75        if (intent != null) {
 76            startActivity(intent);
 77            finish();
 78            return;
 79        }
 80        this.inviteUri = xmppUri;
 81    }
 82
 83    @Override
 84    protected void refreshUiReal() {
 85
 86    }
 87
 88    @Override
 89    void onBackendConnected() {
 90
 91    }
 92
 93    @Override
 94    public void onStart() {
 95        super.onStart();
 96        final int theme = findTheme();
 97        if (this.mTheme != theme) {
 98            recreate();
 99        }
100        new InstallReferrerUtils(this);
101    }
102
103    @Override
104    public void onStop() {
105        super.onStop();
106    }
107
108    @Override
109    public void onNewIntent(Intent intent) {
110        if (intent != null) {
111            setIntent(intent);
112        }
113    }
114
115    @Override
116    protected void onCreate(final Bundle savedInstanceState) {
117        if (getResources().getBoolean(R.bool.portrait_only)) {
118            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
119        }
120        super.onCreate(savedInstanceState);
121        ActivityWelcomeBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_welcome);
122        setSupportActionBar(binding.toolbar);
123        configureActionBar(getSupportActionBar(), false);
124        binding.registerNewAccount.setOnClickListener(v -> {
125            final Intent intent = new Intent(this, MagicCreateActivity.class);
126            addInviteUri(intent);
127            startActivity(intent);
128        });
129        binding.useExisting.setOnClickListener(v -> {
130            final List<Account> accounts = xmppConnectionService.getAccounts();
131            Intent intent = new Intent(WelcomeActivity.this, EditAccountActivity.class);
132            intent.putExtra(EditAccountActivity.EXTRA_FORCE_REGISTER, false);
133            if (accounts.size() == 1) {
134                intent.putExtra("jid", accounts.get(0).getJid().asBareJid().toString());
135                intent.putExtra("init", true);
136            } else if (accounts.size() >= 1) {
137                intent = new Intent(WelcomeActivity.this, ManageAccountActivity.class);
138            }
139            addInviteUri(intent);
140            startActivity(intent);
141        });
142        binding.useSnikket.setOnClickListener(v -> {
143            final List<Account> accounts = xmppConnectionService.getAccounts();
144            Intent intent = new Intent(WelcomeActivity.this, EditAccountActivity.class);
145            intent.putExtra(EditAccountActivity.EXTRA_FORCE_REGISTER, false);
146            intent.putExtra("snikket", true);
147            if (accounts.size() == 1) {
148                intent.putExtra("jid", accounts.get(0).getJid().asBareJid().toString());
149                intent.putExtra("init", true);
150            } else if (accounts.size() >= 1) {
151                intent = new Intent(WelcomeActivity.this, ManageAccountActivity.class);
152            }
153            addInviteUri(intent);
154            startActivity(intent);
155        });
156    }
157
158    @Override
159    public boolean onCreateOptionsMenu(Menu menu) {
160        getMenuInflater().inflate(R.menu.welcome_menu, menu);
161        final MenuItem scan = menu.findItem(R.id.action_scan_qr_code);
162        scan.setVisible(Compatibility.hasFeatureCamera(this));
163        return super.onCreateOptionsMenu(menu);
164    }
165
166
167
168    @Override
169    public boolean onOptionsItemSelected(MenuItem item) {
170        switch (item.getItemId()) {
171            case R.id.action_import_backup:
172                if (hasStoragePermission(REQUEST_IMPORT_BACKUP)) {
173                    startActivity(new Intent(this, ImportBackupActivity.class));
174                }
175                break;
176            case R.id.action_scan_qr_code:
177                UriHandlerActivity.scan(this, true);
178                break;
179            case R.id.action_add_account_with_cert:
180                addAccountFromKey();
181                break;
182        }
183        return super.onOptionsItemSelected(item);
184    }
185
186    private void addAccountFromKey() {
187        try {
188            KeyChain.choosePrivateKeyAlias(this, this, null, null, null, -1, null);
189        } catch (ActivityNotFoundException e) {
190            Toast.makeText(this, R.string.device_does_not_support_certificates, Toast.LENGTH_LONG).show();
191        }
192    }
193
194    @Override
195    public void alias(final String alias) {
196        if (alias != null) {
197            xmppConnectionService.createAccountFromKey(alias, this);
198        }
199    }
200
201    @Override
202    public void onAccountCreated(final Account account) {
203        final Intent intent = new Intent(this, EditAccountActivity.class);
204        intent.putExtra("jid", account.getJid().asBareJid().toEscapedString());
205        intent.putExtra("init", true);
206        addInviteUri(intent);
207        startActivity(intent);
208    }
209
210    @Override
211    public void informUser(final int r) {
212        runOnUiThread(() -> Toast.makeText(this, r, Toast.LENGTH_LONG).show());
213    }
214
215    @Override
216    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
217        UriHandlerActivity.onRequestPermissionResult(this, requestCode, grantResults);
218        if (grantResults.length > 0) {
219            if (allGranted(grantResults)) {
220                switch (requestCode) {
221                    case REQUEST_IMPORT_BACKUP:
222                        startActivity(new Intent(this, ImportBackupActivity.class));
223                        break;
224                }
225            } else if (Arrays.asList(permissions).contains(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
226                Toast.makeText(this, R.string.no_storage_permission, Toast.LENGTH_SHORT).show();
227            }
228        }
229        if (writeGranted(grantResults, permissions)) {
230            if (xmppConnectionService != null) {
231                xmppConnectionService.restartFileObserver();
232            }
233        }
234    }
235
236    public void addInviteUri(Intent to) {
237        final Intent from = getIntent();
238        if (from != null && from.hasExtra(StartConversationActivity.EXTRA_INVITE_URI)) {
239            final String invite = from.getStringExtra(StartConversationActivity.EXTRA_INVITE_URI);
240            to.putExtra(StartConversationActivity.EXTRA_INVITE_URI, invite);
241        } else if (this.inviteUri != null) {
242            Log.d(Config.LOGTAG, "injecting referrer uri into on-boarding flow");
243            to.putExtra(StartConversationActivity.EXTRA_INVITE_URI, this.inviteUri.toString());
244        }
245    }
246
247}