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