UriHandlerActivity.java

  1package eu.siacs.conversations.ui;
  2
  3import android.Manifest;
  4import android.app.Activity;
  5import android.content.Intent;
  6import android.content.pm.PackageManager;
  7import android.net.Uri;
  8import android.os.Build;
  9import android.os.Bundle;
 10import android.support.v4.content.ContextCompat;
 11import android.support.v7.app.AppCompatActivity;
 12import android.util.Log;
 13import android.widget.Toast;
 14
 15import java.util.List;
 16import java.util.regex.Matcher;
 17import java.util.regex.Pattern;
 18
 19import eu.siacs.conversations.Config;
 20import eu.siacs.conversations.R;
 21import eu.siacs.conversations.persistance.DatabaseBackend;
 22import eu.siacs.conversations.utils.SignupUtils;
 23import eu.siacs.conversations.utils.XmppUri;
 24import rocks.xmpp.addr.Jid;
 25
 26public class UriHandlerActivity extends AppCompatActivity {
 27
 28    public static final String ACTION_SCAN_QR_CODE = "scan_qr_code";
 29    private static final int REQUEST_SCAN_QR_CODE = 0x1234;
 30    private static final int REQUEST_CAMERA_PERMISSIONS_TO_SCAN = 0x6789;
 31
 32    private boolean handled = false;
 33
 34    public static void scan(Activity activity) {
 35        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M || ContextCompat.checkSelfPermission(activity, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
 36            Intent intent = new Intent(activity, UriHandlerActivity.class);
 37            intent.setAction(UriHandlerActivity.ACTION_SCAN_QR_CODE);
 38            intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
 39            activity.startActivity(intent);
 40        } else {
 41            activity.requestPermissions(new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA_PERMISSIONS_TO_SCAN);
 42        }
 43    }
 44
 45    public static void onRequestPermissionResult(Activity activity, int requestCode, int[] grantResults) {
 46        if (requestCode != REQUEST_CAMERA_PERMISSIONS_TO_SCAN) {
 47            return;
 48        }
 49        if (grantResults.length > 0) {
 50            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
 51                scan(activity);
 52            } else {
 53                Toast.makeText(activity, R.string.qr_code_scanner_needs_access_to_camera, Toast.LENGTH_SHORT).show();
 54            }
 55        }
 56    }
 57
 58    @Override
 59    protected void onCreate(Bundle savedInstanceState) {
 60        super.onCreate(savedInstanceState);
 61        this.handled = savedInstanceState != null && savedInstanceState.getBoolean("handled", false);
 62        getLayoutInflater().inflate(R.layout.toolbar, findViewById(android.R.id.content));
 63        setSupportActionBar(findViewById(R.id.toolbar));
 64    }
 65
 66    @Override
 67    public void onStart() {
 68        super.onStart();
 69        handleIntent(getIntent());
 70    }
 71
 72    @Override
 73    public void onSaveInstanceState(Bundle savedInstanceState) {
 74        savedInstanceState.putBoolean("handled", this.handled);
 75        super.onSaveInstanceState(savedInstanceState);
 76    }
 77
 78    @Override
 79    public void onNewIntent(Intent intent) {
 80        handleIntent(intent);
 81    }
 82
 83    private void handleUri(Uri uri) {
 84        handleUri(uri, false);
 85    }
 86
 87    private void handleUri(Uri uri, final boolean scanned) {
 88        final Intent intent;
 89        final XmppUri xmppUri = new XmppUri(uri);
 90        final List<Jid> accounts = DatabaseBackend.getInstance(this).getAccountJids(true);
 91
 92        if (SignupUtils.isSupportTokenRegistry() && xmppUri.isJidValid()) {
 93            final String preauth = xmppUri.getParamater("preauth");
 94            final Jid jid = xmppUri.getJid();
 95            if (xmppUri.isAction(XmppUri.ACTION_REGISTER)) {
 96                if (jid.isDomainJid()) {
 97                    intent = SignupUtils.getTokenRegistrationIntent(this, jid.getDomain(), preauth);
 98                    startActivity(intent);
 99                    return;
100                }
101                return;
102            }
103            if (xmppUri.isAction(XmppUri.ACTION_ROSTER) && "y".equals(xmppUri.getParamater("ibr"))) {
104                intent = SignupUtils.getTokenRegistrationIntent(this, jid.getDomain(), preauth);
105                intent.putExtra(StartConversationActivity.EXTRA_INVITE_URI, xmppUri.toString());
106                startActivity(intent);
107                return;
108            }
109        }
110
111        if (accounts.size() == 0) {
112            if (xmppUri.isJidValid()) {
113                intent = SignupUtils.getSignUpIntent(this);
114                intent.putExtra(StartConversationActivity.EXTRA_INVITE_URI, xmppUri.toString());
115                startActivity(intent);
116            } else {
117                Toast.makeText(this, R.string.invalid_jid, Toast.LENGTH_SHORT).show();
118            }
119
120            return;
121        }
122
123        if (xmppUri.isAction(XmppUri.ACTION_MESSAGE)) {
124
125            final Jid jid = xmppUri.getJid();
126            final String body = xmppUri.getBody();
127
128            if (jid != null) {
129                Class clazz;
130                try {
131                    clazz = Class.forName("eu.siacs.conversations.ui.ShareViaAccountActivity");
132                } catch (ClassNotFoundException e) {
133                    clazz = null;
134
135                }
136                if (clazz != null) {
137                    intent = new Intent(this, clazz);
138                    intent.putExtra("contact", jid.toEscapedString());
139                    intent.putExtra("body", body);
140                } else {
141                    intent = new Intent(this, StartConversationActivity.class);
142                    intent.setAction(Intent.ACTION_VIEW);
143                    intent.setData(uri);
144                    intent.putExtra("account", accounts.get(0).toEscapedString());
145                }
146
147            } else {
148                intent = new Intent(this, ShareWithActivity.class);
149                intent.setAction(Intent.ACTION_SEND);
150                intent.setType("text/plain");
151                intent.putExtra(Intent.EXTRA_TEXT, body);
152            }
153        } else if (accounts.contains(xmppUri.getJid())) {
154            intent = new Intent(getApplicationContext(), EditAccountActivity.class);
155            intent.setAction(Intent.ACTION_VIEW);
156            intent.putExtra("jid", xmppUri.getJid().asBareJid().toString());
157            intent.setData(uri);
158            intent.putExtra("scanned", scanned);
159        } else if (xmppUri.isJidValid()) {
160            intent = new Intent(getApplicationContext(), StartConversationActivity.class);
161            intent.setAction(Intent.ACTION_VIEW);
162            intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
163            intent.putExtra("scanned", scanned);
164            intent.setData(uri);
165        } else {
166            Toast.makeText(this, R.string.invalid_jid, Toast.LENGTH_SHORT).show();
167            return;
168        }
169
170        startActivity(intent);
171    }
172
173    private void handleIntent(Intent data) {
174        if (handled) {
175            return;
176        }
177        if (data == null || data.getAction() == null) {
178            finish();
179            return;
180        }
181
182        handled = true;
183
184        switch (data.getAction()) {
185            case Intent.ACTION_VIEW:
186            case Intent.ACTION_SENDTO:
187                handleUri(data.getData());
188                break;
189            case ACTION_SCAN_QR_CODE:
190                Intent intent = new Intent(this, ScanActivity.class);
191                startActivityForResult(intent, REQUEST_SCAN_QR_CODE);
192                return;
193        }
194
195        finish();
196    }
197
198    private static final Pattern VCARD_XMPP_PATTERN = Pattern.compile("\nIMPP([^:]*):(xmpp:.+)\n");
199
200    @Override
201    public void onActivityResult(int requestCode, int resultCode, Intent intent) {
202        super.onActivityResult(requestCode, requestCode, intent);
203        if (requestCode == REQUEST_SCAN_QR_CODE && resultCode == RESULT_OK) {
204            String result = intent.getStringExtra(ScanActivity.INTENT_EXTRA_RESULT);
205            if (result != null) {
206                if (result.startsWith("BEGIN:VCARD\n")) {
207                    Matcher matcher = VCARD_XMPP_PATTERN.matcher(result);
208                    if (matcher.find()) {
209                        result = matcher.group(2);
210                    }
211                }
212                Uri uri = Uri.parse(result);
213                handleUri(uri, true);
214            }
215        }
216        finish();
217    }
218}