Package visibility changes

pull/180/head
M66B 5 years ago
parent 3dac4d407e
commit f30a175836

@ -39,9 +39,22 @@
<!-- Android 11: https://developer.android.com/preview/privacy/package-visibility --> <!-- Android 11: https://developer.android.com/preview/privacy/package-visibility -->
<queries> <queries>
<intent> <!--intent>
<action android:name="android.intent.action.VIEW" /> <action android:name="android.intent.action.VIEW" />
<data android:mimeType="*/*" /> <data android:mimeType="*/*" />
</intent-->
<!-- Customtabs / AppAuth-Android -->
<intent>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https" />
</intent>
<intent>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="http" />
</intent> </intent>
<intent> <intent>

@ -386,7 +386,7 @@ abstract class ActivityBase extends AppCompatActivity implements SharedPreferenc
try { try {
super.startActivity(intent); super.startActivity(intent);
} catch (ActivityNotFoundException ex) { } catch (ActivityNotFoundException ex) {
Log.e(ex); Log.w(ex);
ToastEx.makeText(this, getString(R.string.title_no_viewer, intent.getAction()), Toast.LENGTH_LONG).show(); ToastEx.makeText(this, getString(R.string.title_no_viewer, intent.getAction()), Toast.LENGTH_LONG).show();
} }
} }
@ -396,7 +396,7 @@ abstract class ActivityBase extends AppCompatActivity implements SharedPreferenc
try { try {
super.startActivityForResult(intent, requestCode); super.startActivityForResult(intent, requestCode);
} catch (ActivityNotFoundException ex) { } catch (ActivityNotFoundException ex) {
Log.e(ex); Log.w(ex);
ToastEx.makeText(this, getString(R.string.title_no_viewer, intent.getAction()), Toast.LENGTH_LONG).show(); ToastEx.makeText(this, getString(R.string.title_no_viewer, intent.getAction()), Toast.LENGTH_LONG).show();
} }
} }
@ -533,7 +533,7 @@ abstract class ActivityBase extends AppCompatActivity implements SharedPreferenc
@Override @Override
public boolean shouldUpRecreateTask(Intent targetIntent) { public boolean shouldUpRecreateTask(Intent targetIntent) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q + 1) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
ComponentName cn = targetIntent.getComponent(); ComponentName cn = targetIntent.getComponent();
if (cn != null && BuildConfig.APPLICATION_ID.equals(cn.getPackageName())) if (cn != null && BuildConfig.APPLICATION_ID.equals(cn.getPackageName()))
return false; return false;

@ -252,11 +252,10 @@ public class ActivityEML extends ActivityBase {
if (!TextUtils.isEmpty(apart.attachment.name)) if (!TextUtils.isEmpty(apart.attachment.name))
create.putExtra(Intent.EXTRA_TITLE, apart.attachment.name); create.putExtra(Intent.EXTRA_TITLE, apart.attachment.name);
Helper.openAdvanced(create); Helper.openAdvanced(create);
if (create.resolveActivity(getPackageManager()) == null) if (create.resolveActivity(getPackageManager()) == null) // system whitelisted
ToastEx.makeText(ActivityEML.this, R.string.title_no_saf, Toast.LENGTH_LONG).show(); ToastEx.makeText(ActivityEML.this, R.string.title_no_saf, Toast.LENGTH_LONG).show();
else else
startActivityForResult(Helper.getChooser(ActivityEML.this, create), REQUEST_ATTACHMENT); startActivityForResult(Helper.getChooser(ActivityEML.this, create), REQUEST_ATTACHMENT);
} }
}); });
rvAttachment.setAdapter(adapter); rvAttachment.setAdapter(adapter);

@ -410,7 +410,7 @@ public class ActivitySetup extends ActivityBase implements FragmentManager.OnBac
private void askPassword(final boolean export) { private void askPassword(final boolean export) {
Intent intent = (export ? getIntentExport() : getIntentImport()); Intent intent = (export ? getIntentExport() : getIntentImport());
if (intent.resolveActivity(getPackageManager()) == null) { if (intent.resolveActivity(getPackageManager()) == null) { // // system/GET_CONTENT whitelisted
ToastEx.makeText(this, R.string.title_no_saf, Toast.LENGTH_LONG).show(); ToastEx.makeText(this, R.string.title_no_saf, Toast.LENGTH_LONG).show();
return; return;
} }
@ -1266,7 +1266,7 @@ public class ActivitySetup extends ActivityBase implements FragmentManager.OnBac
Intent open = new Intent(Intent.ACTION_GET_CONTENT); Intent open = new Intent(Intent.ACTION_GET_CONTENT);
open.addCategory(Intent.CATEGORY_OPENABLE); open.addCategory(Intent.CATEGORY_OPENABLE);
open.setType("*/*"); open.setType("*/*");
if (open.resolveActivity(getPackageManager()) == null) if (open.resolveActivity(getPackageManager()) == null) // system whitelisted
ToastEx.makeText(this, R.string.title_no_saf, Toast.LENGTH_LONG).show(); ToastEx.makeText(this, R.string.title_no_saf, Toast.LENGTH_LONG).show();
else else
startActivityForResult(Helper.getChooser(this, open), REQUEST_IMPORT_CERTIFICATE); startActivityForResult(Helper.getChooser(this, open), REQUEST_IMPORT_CERTIFICATE);

@ -489,15 +489,14 @@ public class ActivityView extends ActivityBilling implements FragmentManager.OnB
} }
}).setExternal(true)); }).setExternal(true));
if (Helper.getIntentIssue(this).resolveActivity(pm) != null) extra.add(new NavMenuItem(R.drawable.baseline_feedback_24, R.string.menu_issue, new Runnable() {
extra.add(new NavMenuItem(R.drawable.baseline_feedback_24, R.string.menu_issue, new Runnable() { @Override
@Override public void run() {
public void run() { if (!drawerLayout.isLocked(drawerContainer))
if (!drawerLayout.isLocked(drawerContainer)) drawerLayout.closeDrawer(drawerContainer);
drawerLayout.closeDrawer(drawerContainer); onMenuIssue();
onMenuIssue(); }
} }).setExternal(true));
}).setExternal(true));
if (Helper.isPlayStoreInstall() && false) if (Helper.isPlayStoreInstall() && false)
extra.add(new NavMenuItem(R.drawable.baseline_bug_report_24, R.string.menu_test, new Runnable() { extra.add(new NavMenuItem(R.drawable.baseline_bug_report_24, R.string.menu_test, new Runnable() {
@ -543,18 +542,16 @@ public class ActivityView extends ActivityBilling implements FragmentManager.OnB
} }
})); }));
if ((getIntentInvite(this).resolveActivity(pm) != null)) extra.add(new NavMenuItem(R.drawable.baseline_people_24, R.string.menu_invite, new Runnable() {
extra.add(new NavMenuItem(R.drawable.baseline_people_24, R.string.menu_invite, new Runnable() { @Override
@Override public void run() {
public void run() { if (!drawerLayout.isLocked(drawerContainer))
if (!drawerLayout.isLocked(drawerContainer)) drawerLayout.closeDrawer(drawerContainer);
drawerLayout.closeDrawer(drawerContainer); onMenuInvite();
onMenuInvite(); }
} }).setExternal(true));
}).setExternal(true));
if ((Helper.isPlayStoreInstall() || BuildConfig.DEBUG) && if ((Helper.isPlayStoreInstall() || BuildConfig.DEBUG))
Helper.getIntentRate(this).resolveActivity(pm) != null)
extra.add(new NavMenuItem(R.drawable.baseline_star_24, R.string.menu_rate, new Runnable() { extra.add(new NavMenuItem(R.drawable.baseline_star_24, R.string.menu_rate, new Runnable() {
@Override @Override
public void run() { public void run() {
@ -564,15 +561,14 @@ public class ActivityView extends ActivityBilling implements FragmentManager.OnB
} }
}).setExternal(true)); }).setExternal(true));
if (getIntentOtherApps().resolveActivity(pm) != null) extra.add(new NavMenuItem(R.drawable.baseline_get_app_24, R.string.menu_other, new Runnable() {
extra.add(new NavMenuItem(R.drawable.baseline_get_app_24, R.string.menu_other, new Runnable() { @Override
@Override public void run() {
public void run() { if (!drawerLayout.isLocked(drawerContainer))
if (!drawerLayout.isLocked(drawerContainer)) drawerLayout.closeDrawer(drawerContainer);
drawerLayout.closeDrawer(drawerContainer); onMenuOtherApps();
onMenuOtherApps(); }
} }).setExternal(true));
}).setExternal(true));
adapterNavMenuExtra.set(extra); adapterNavMenuExtra.set(extra);
@ -883,12 +879,10 @@ public class ActivityView extends ActivityBilling implements FragmentManager.OnB
.setVisibility(NotificationCompat.VISIBILITY_SECRET); .setVisibility(NotificationCompat.VISIBILITY_SECRET);
Intent update = new Intent(Intent.ACTION_VIEW, Uri.parse(info.html_url)); Intent update = new Intent(Intent.ACTION_VIEW, Uri.parse(info.html_url));
if (update.resolveActivity(getPackageManager()) != null) { update.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
update.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); PendingIntent piUpdate = PendingIntent.getActivity(
PendingIntent piUpdate = PendingIntent.getActivity( ActivityView.this, REQUEST_UPDATE, update, PendingIntent.FLAG_UPDATE_CURRENT);
ActivityView.this, REQUEST_UPDATE, update, PendingIntent.FLAG_UPDATE_CURRENT); builder.setContentIntent(piUpdate);
builder.setContentIntent(piUpdate);
}
try { try {
NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

@ -217,7 +217,7 @@ public class AdapterContact extends RecyclerView.Adapter<AdapterContact.ViewHold
if (contact.state != EntityContact.STATE_IGNORE) if (contact.state != EntityContact.STATE_IGNORE)
popupMenu.getMenu().add(Menu.NONE, R.string.title_advanced_never_favorite, 1, R.string.title_advanced_never_favorite); popupMenu.getMenu().add(Menu.NONE, R.string.title_advanced_never_favorite, 1, R.string.title_advanced_never_favorite);
if (share.resolveActivity(context.getPackageManager()) != null) if (share.resolveActivity(context.getPackageManager()) != null) // system whitelisted
popupMenu.getMenu().add(Menu.NONE, R.string.title_share, 2, R.string.title_share); popupMenu.getMenu().add(Menu.NONE, R.string.title_share, 2, R.string.title_share);
if (ShortcutManagerCompat.isRequestPinShortcutSupported(context)) if (ShortcutManagerCompat.isRequestPinShortcutSupported(context))
popupMenu.getMenu().add(Menu.NONE, R.string.title_pin, 3, R.string.title_pin); popupMenu.getMenu().add(Menu.NONE, R.string.title_pin, 3, R.string.title_pin);

@ -29,6 +29,7 @@ import android.app.NotificationChannel;
import android.app.NotificationManager; import android.app.NotificationManager;
import android.app.Person; import android.app.Person;
import android.app.RemoteAction; import android.app.RemoteAction;
import android.content.ActivityNotFoundException;
import android.content.ClipData; import android.content.ClipData;
import android.content.ClipboardManager; import android.content.ClipboardManager;
import android.content.ContentResolver; import android.content.ContentResolver;
@ -2920,8 +2921,14 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
Uri lookupUri = (Uri) ibAvatar.getTag(); Uri lookupUri = (Uri) ibAvatar.getTag();
if (lookupUri != null) { if (lookupUri != null) {
Intent intent = new Intent(Intent.ACTION_VIEW, lookupUri); Intent intent = new Intent(Intent.ACTION_VIEW, lookupUri);
if (intent.resolveActivity(context.getPackageManager()) != null) try {
context.startActivity(intent); context.startActivity(intent);
} catch (ActivityNotFoundException ex) {
Log.w(ex);
ToastEx.makeText(context,
context.getString(R.string.title_no_viewer, intent.getAction()),
Toast.LENGTH_LONG).show();
}
} }
} }
@ -3216,7 +3223,7 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
private void onPickContact(String name, String email) { private void onPickContact(String name, String email) {
Intent pick = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI); Intent pick = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
if (pick.resolveActivity(context.getPackageManager()) == null) if (pick.resolveActivity(context.getPackageManager()) == null) // system whitelisted
Snackbar.make(view, R.string.title_no_contacts, Snackbar.LENGTH_LONG).show(); Snackbar.make(view, R.string.title_no_contacts, Snackbar.LENGTH_LONG).show();
else { else {
properties.setValue("name", name); properties.setValue("name", name);
@ -3236,7 +3243,7 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
insert.setType(ContactsContract.Contacts.CONTENT_TYPE); insert.setType(ContactsContract.Contacts.CONTENT_TYPE);
PackageManager pm = context.getPackageManager(); PackageManager pm = context.getPackageManager();
if (insert.resolveActivity(pm) == null) if (insert.resolveActivity(pm) == null) // system whitelisted
Snackbar.make(parentFragment.getView(), Snackbar.make(parentFragment.getView(),
R.string.title_no_contacts, Snackbar.LENGTH_LONG).show(); R.string.title_no_contacts, Snackbar.LENGTH_LONG).show();
else else
@ -3253,7 +3260,7 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
edit.setDataAndTypeAndNormalize(lookupUri, ContactsContract.Contacts.CONTENT_ITEM_TYPE); edit.setDataAndTypeAndNormalize(lookupUri, ContactsContract.Contacts.CONTENT_ITEM_TYPE);
PackageManager pm = context.getPackageManager(); PackageManager pm = context.getPackageManager();
if (edit.resolveActivity(pm) == null) if (edit.resolveActivity(pm) == null) // system whitelisted
Snackbar.make(parentFragment.getView(), Snackbar.make(parentFragment.getView(),
R.string.title_no_contacts, Snackbar.LENGTH_LONG).show(); R.string.title_no_contacts, Snackbar.LENGTH_LONG).show();
else else
@ -4331,7 +4338,7 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
} }
PackageManager pm = context.getPackageManager(); PackageManager pm = context.getPackageManager();
if (intent.resolveActivity(pm) == null) if (intent.resolveActivity(pm) == null) // system whitelisted
Snackbar.make(parentFragment.getView(), Snackbar.make(parentFragment.getView(),
context.getString(R.string.title_no_viewer, intent.getAction()), context.getString(R.string.title_no_viewer, intent.getAction()),
Snackbar.LENGTH_LONG). Snackbar.LENGTH_LONG).

@ -27,6 +27,7 @@ import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.content.IntentSender; import android.content.IntentSender;
import android.content.pm.PackageManager;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.net.Uri; import android.net.Uri;
import android.os.Build; import android.os.Build;
@ -135,7 +136,7 @@ public class FragmentBase extends Fragment {
try { try {
super.startActivity(intent); super.startActivity(intent);
} catch (ActivityNotFoundException ex) { } catch (ActivityNotFoundException ex) {
Log.e(ex); Log.w(ex);
ToastEx.makeText(getContext(), getString(R.string.title_no_viewer, intent.getAction()), Toast.LENGTH_LONG).show(); ToastEx.makeText(getContext(), getString(R.string.title_no_viewer, intent.getAction()), Toast.LENGTH_LONG).show();
} }
} }
@ -145,7 +146,7 @@ public class FragmentBase extends Fragment {
try { try {
super.startActivityForResult(intent, requestCode); super.startActivityForResult(intent, requestCode);
} catch (ActivityNotFoundException ex) { } catch (ActivityNotFoundException ex) {
Log.e(ex); Log.w(ex);
ToastEx.makeText(getContext(), getString(R.string.title_no_viewer, intent.getAction()), Toast.LENGTH_LONG).show(); ToastEx.makeText(getContext(), getString(R.string.title_no_viewer, intent.getAction()), Toast.LENGTH_LONG).show();
} }
} }
@ -351,7 +352,8 @@ public class FragmentBase extends Fragment {
create.setType(intent.getStringExtra("type")); create.setType(intent.getStringExtra("type"));
create.putExtra(Intent.EXTRA_TITLE, intent.getStringExtra("name")); create.putExtra(Intent.EXTRA_TITLE, intent.getStringExtra("name"));
Helper.openAdvanced(create); Helper.openAdvanced(create);
if (create.resolveActivity(getContext().getPackageManager()) == null) PackageManager pm = getContext().getPackageManager();
if (create.resolveActivity(pm) == null) // system whitelisted
ToastEx.makeText(getContext(), R.string.title_no_saf, Toast.LENGTH_LONG).show(); ToastEx.makeText(getContext(), R.string.title_no_saf, Toast.LENGTH_LONG).show();
else else
startActivityForResult(Helper.getChooser(getContext(), create), REQUEST_ATTACHMENT); startActivityForResult(Helper.getChooser(getContext(), create), REQUEST_ATTACHMENT);
@ -361,7 +363,8 @@ public class FragmentBase extends Fragment {
message = intent.getLongExtra("id", -1); message = intent.getLongExtra("id", -1);
Intent tree = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE); Intent tree = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
Helper.openAdvanced(tree); Helper.openAdvanced(tree);
if (tree.resolveActivity(getContext().getPackageManager()) == null) PackageManager pm = getContext().getPackageManager();
if (tree.resolveActivity(pm) == null) // system whitelisted
ToastEx.makeText(getContext(), R.string.title_no_saf, Toast.LENGTH_LONG).show(); ToastEx.makeText(getContext(), R.string.title_no_saf, Toast.LENGTH_LONG).show();
else else
startActivityForResult(Helper.getChooser(getContext(), tree), REQUEST_ATTACHMENTS); startActivityForResult(Helper.getChooser(getContext(), tree), REQUEST_ATTACHMENTS);

@ -438,7 +438,8 @@ public class FragmentCompose extends FragmentBase {
} }
Intent pick = new Intent(Intent.ACTION_PICK, ContactsContract.CommonDataKinds.Email.CONTENT_URI); Intent pick = new Intent(Intent.ACTION_PICK, ContactsContract.CommonDataKinds.Email.CONTENT_URI);
if (pick.resolveActivity(getContext().getPackageManager()) == null) PackageManager pm = getContext().getPackageManager();
if (pick.resolveActivity(pm) == null) // system whitelisted
Snackbar.make(view, R.string.title_no_contacts, Snackbar.LENGTH_LONG).show(); Snackbar.make(view, R.string.title_no_contacts, Snackbar.LENGTH_LONG).show();
else else
startActivityForResult(Helper.getChooser(getContext(), pick), request); startActivityForResult(Helper.getChooser(getContext(), pick), request);
@ -1472,7 +1473,7 @@ public class FragmentCompose extends FragmentBase {
// https://developer.android.com/reference/android/provider/MediaStore.Audio.Media.html#RECORD_SOUND_ACTION // https://developer.android.com/reference/android/provider/MediaStore.Audio.Media.html#RECORD_SOUND_ACTION
PackageManager pm = getContext().getPackageManager(); PackageManager pm = getContext().getPackageManager();
Intent intent = new Intent(MediaStore.Audio.Media.RECORD_SOUND_ACTION); Intent intent = new Intent(MediaStore.Audio.Media.RECORD_SOUND_ACTION);
if (intent.resolveActivity(pm) == null) { if (intent.resolveActivity(pm) == null) { // action whitelisted
Snackbar snackbar = Snackbar.make(view, getString(R.string.title_no_recorder), Snackbar.LENGTH_INDEFINITE); Snackbar snackbar = Snackbar.make(view, getString(R.string.title_no_recorder), Snackbar.LENGTH_INDEFINITE);
snackbar.setAction(R.string.title_fix, new View.OnClickListener() { snackbar.setAction(R.string.title_fix, new View.OnClickListener() {
@Override @Override
@ -1510,7 +1511,7 @@ public class FragmentCompose extends FragmentBase {
intent.setType("*/*"); intent.setType("*/*");
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true); intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
PackageManager pm = getContext().getPackageManager(); PackageManager pm = getContext().getPackageManager();
if (intent.resolveActivity(pm) == null) if (intent.resolveActivity(pm) == null) // system whitelisted
noStorageAccessFramework(); noStorageAccessFramework();
else else
startActivityForResult(Helper.getChooser(getContext(), intent), REQUEST_ATTACHMENT); startActivityForResult(Helper.getChooser(getContext(), intent), REQUEST_ATTACHMENT);
@ -1632,7 +1633,8 @@ public class FragmentCompose extends FragmentBase {
public void onNothingSelected() { public void onNothingSelected() {
Snackbar snackbar = Snackbar.make(view, R.string.title_no_key, Snackbar.LENGTH_LONG); Snackbar snackbar = Snackbar.make(view, R.string.title_no_key, Snackbar.LENGTH_LONG);
final Intent intent = KeyChain.createInstallIntent(); final Intent intent = KeyChain.createInstallIntent();
if (intent.resolveActivity(getContext().getPackageManager()) != null) PackageManager pm = getContext().getPackageManager();
if (intent.resolveActivity(pm) != null) // package whitelisted
snackbar.setAction(R.string.title_fix, new View.OnClickListener() { snackbar.setAction(R.string.title_fix, new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
@ -1698,7 +1700,8 @@ public class FragmentCompose extends FragmentBase {
} }
else { else {
Snackbar snackbar = Snackbar.make(view, R.string.title_no_openpgp, Snackbar.LENGTH_LONG); Snackbar snackbar = Snackbar.make(view, R.string.title_no_openpgp, Snackbar.LENGTH_LONG);
if (Helper.getIntentOpenKeychain().resolveActivity(getContext().getPackageManager()) != null) PackageManager pm = getContext().getPackageManager();
if (Helper.getIntentOpenKeychain().resolveActivity(pm) != null) // package whitelisted
snackbar.setAction(R.string.title_fix, new View.OnClickListener() { snackbar.setAction(R.string.title_fix, new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
@ -1874,7 +1877,7 @@ public class FragmentCompose extends FragmentBase {
// https://developer.android.com/training/camera/photobasics // https://developer.android.com/training/camera/photobasics
PackageManager pm = getContext().getPackageManager(); PackageManager pm = getContext().getPackageManager();
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (intent.resolveActivity(pm) == null) { if (intent.resolveActivity(pm) == null) { // action whitelisted
Snackbar snackbar = Snackbar.make(view, getString(R.string.title_no_camera), Snackbar.LENGTH_LONG); Snackbar snackbar = Snackbar.make(view, getString(R.string.title_no_camera), Snackbar.LENGTH_LONG);
snackbar.setAction(R.string.title_fix, new View.OnClickListener() { snackbar.setAction(R.string.title_fix, new View.OnClickListener() {
@Override @Override
@ -1903,7 +1906,7 @@ public class FragmentCompose extends FragmentBase {
intent.setType("image/*"); intent.setType("image/*");
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true); intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
PackageManager pm = getContext().getPackageManager(); PackageManager pm = getContext().getPackageManager();
if (intent.resolveActivity(pm) == null) if (intent.resolveActivity(pm) == null) // GET_CONTENT whitelisted
noStorageAccessFramework(); noStorageAccessFramework();
else else
startActivityForResult(Helper.getChooser(getContext(), intent), REQUEST_IMAGE_FILE); startActivityForResult(Helper.getChooser(getContext(), intent), REQUEST_IMAGE_FILE);

@ -163,7 +163,7 @@ public class FragmentDialogBase extends DialogFragment {
try { try {
super.startActivity(intent); super.startActivity(intent);
} catch (ActivityNotFoundException ex) { } catch (ActivityNotFoundException ex) {
Log.e(ex); Log.w(ex);
ToastEx.makeText(getContext(), getString(R.string.title_no_viewer, intent.getAction()), Toast.LENGTH_LONG).show(); ToastEx.makeText(getContext(), getString(R.string.title_no_viewer, intent.getAction()), Toast.LENGTH_LONG).show();
} }
} }
@ -173,7 +173,7 @@ public class FragmentDialogBase extends DialogFragment {
try { try {
super.startActivityForResult(intent, requestCode); super.startActivityForResult(intent, requestCode);
} catch (ActivityNotFoundException ex) { } catch (ActivityNotFoundException ex) {
Log.e(ex); Log.w(ex);
ToastEx.makeText(getContext(), getString(R.string.title_no_viewer, intent.getAction()), Toast.LENGTH_LONG).show(); ToastEx.makeText(getContext(), getString(R.string.title_no_viewer, intent.getAction()), Toast.LENGTH_LONG).show();
} }
} }

@ -125,7 +125,7 @@ public class FragmentGmail extends FragmentBase {
null, null,
null); null);
PackageManager pm = getContext().getPackageManager(); PackageManager pm = getContext().getPackageManager();
if (intent.resolveActivity(pm) == null) if (intent.resolveActivity(pm) == null) // system whitelisted
throw new IllegalArgumentException(getString(R.string.title_no_viewer, intent)); throw new IllegalArgumentException(getString(R.string.title_no_viewer, intent));
startActivityForResult(intent, ActivitySetup.REQUEST_CHOOSE_ACCOUNT); startActivityForResult(intent, ActivitySetup.REQUEST_CHOOSE_ACCOUNT);
} catch (Throwable ex) { } catch (Throwable ex) {

@ -3322,12 +3322,6 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences.
if (prefs.getBoolean("review_asked", false)) if (prefs.getBoolean("review_asked", false))
return false; return false;
PackageManager pm = getContext().getPackageManager();
Intent intent = Helper.getIntentRate(getContext());
if (intent.resolveActivity(pm) == null)
return false;
long now = new Date().getTime(); long now = new Date().getTime();
long later = prefs.getLong("review_later", -1); long later = prefs.getLong("review_later", -1);
if (later < 0) { if (later < 0) {
@ -4898,7 +4892,8 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences.
create.setType("*/*"); create.setType("*/*");
create.putExtra(Intent.EXTRA_TITLE, name); create.putExtra(Intent.EXTRA_TITLE, name);
Helper.openAdvanced(create); Helper.openAdvanced(create);
if (create.resolveActivity(getContext().getPackageManager()) == null) PackageManager pm = getContext().getPackageManager();
if (create.resolveActivity(pm) == null) // system whitelisted
Snackbar.make(view, R.string.title_no_saf, Snackbar.LENGTH_LONG).show(); Snackbar.make(view, R.string.title_no_saf, Snackbar.LENGTH_LONG).show();
else else
startActivityForResult(Helper.getChooser(getContext(), create), REQUEST_RAW); startActivityForResult(Helper.getChooser(getContext(), create), REQUEST_RAW);
@ -4958,7 +4953,8 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences.
public void onNothingSelected() { public void onNothingSelected() {
Snackbar snackbar = Snackbar.make(view, R.string.title_no_key, Snackbar.LENGTH_LONG); Snackbar snackbar = Snackbar.make(view, R.string.title_no_key, Snackbar.LENGTH_LONG);
final Intent intent = KeyChain.createInstallIntent(); final Intent intent = KeyChain.createInstallIntent();
if (intent.resolveActivity(getContext().getPackageManager()) != null) PackageManager pm = getContext().getPackageManager();
if (intent.resolveActivity(pm) != null) // system whitelisted
snackbar.setAction(R.string.title_fix, new View.OnClickListener() { snackbar.setAction(R.string.title_fix, new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
@ -4983,7 +4979,8 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences.
onPgp(data, auto); onPgp(data, auto);
} else { } else {
Snackbar snackbar = Snackbar.make(view, R.string.title_no_openpgp, Snackbar.LENGTH_LONG); Snackbar snackbar = Snackbar.make(view, R.string.title_no_openpgp, Snackbar.LENGTH_LONG);
if (Helper.getIntentOpenKeychain().resolveActivity(getContext().getPackageManager()) != null) PackageManager pm = getContext().getPackageManager();
if (Helper.getIntentOpenKeychain().resolveActivity(pm) != null) // package whitelisted
snackbar.setAction(R.string.title_fix, new View.OnClickListener() { snackbar.setAction(R.string.title_fix, new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {

@ -23,6 +23,7 @@ import android.content.ActivityNotFoundException;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
@ -294,7 +295,8 @@ public class FragmentOAuth extends FragmentBase {
Log.i("OAuth request provider=" + provider.id + " uri=" + authRequest.toUri()); Log.i("OAuth request provider=" + provider.id + " uri=" + authRequest.toUri());
Intent authIntent = authService.getAuthorizationRequestIntent(authRequest); Intent authIntent = authService.getAuthorizationRequestIntent(authRequest);
if (authIntent.resolveActivity(getContext().getPackageManager()) == null) PackageManager pm = getContext().getPackageManager();
if (authIntent.resolveActivity(pm) == null) // action whitelisted
throw new ActivityNotFoundException(authIntent.toString()); throw new ActivityNotFoundException(authIntent.toString());
else else
startActivityForResult(authIntent, ActivitySetup.REQUEST_OAUTH); startActivityForResult(authIntent, ActivitySetup.REQUEST_OAUTH);

@ -22,6 +22,7 @@ package eu.faircode.email;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.net.ConnectivityManager; import android.net.ConnectivityManager;
import android.net.Network; import android.net.Network;
import android.net.NetworkCapabilities; import android.net.NetworkCapabilities;
@ -188,8 +189,9 @@ public class FragmentOptionsConnection extends FragmentBase implements SharedPre
}); });
final Intent manage = getIntentConnectivity(); final Intent manage = getIntentConnectivity();
PackageManager pm = getContext().getPackageManager();
btnManage.setVisibility( btnManage.setVisibility(
manage.resolveActivity(getContext().getPackageManager()) == null manage.resolveActivity(pm) == null // system whitelisted
? View.GONE : View.VISIBLE); ? View.GONE : View.VISIBLE);
btnManage.setOnClickListener(new View.OnClickListener() { btnManage.setOnClickListener(new View.OnClickListener() {

@ -117,7 +117,7 @@ public class FragmentOptionsEncryption extends FragmentBase implements SharedPre
tvKeySize = view.findViewById(R.id.tvKeySize); tvKeySize = view.findViewById(R.id.tvKeySize);
Intent intent = new Intent(OpenPgpApi.SERVICE_INTENT_2); Intent intent = new Intent(OpenPgpApi.SERVICE_INTENT_2);
List<ResolveInfo> ris = pm.queryIntentServices(intent, 0); List<ResolveInfo> ris = pm.queryIntentServices(intent, 0); // package whitelisted
for (ResolveInfo ri : ris) for (ResolveInfo ri : ris)
if (ri.serviceInfo != null) if (ri.serviceInfo != null)
openPgpProvider.add(ri.serviceInfo.packageName); openPgpProvider.add(ri.serviceInfo.packageName);
@ -209,7 +209,7 @@ public class FragmentOptionsEncryption extends FragmentBase implements SharedPre
}); });
final Intent importKey = KeyChain.createInstallIntent(); final Intent importKey = KeyChain.createInstallIntent();
btnImportKey.setEnabled(importKey.resolveActivity(pm) != null); btnImportKey.setEnabled(importKey.resolveActivity(pm) != null); // system whitelisted
btnImportKey.setOnClickListener(new View.OnClickListener() { btnImportKey.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
@ -218,7 +218,7 @@ public class FragmentOptionsEncryption extends FragmentBase implements SharedPre
}); });
final Intent security = new Intent(Settings.ACTION_SECURITY_SETTINGS); final Intent security = new Intent(Settings.ACTION_SECURITY_SETTINGS);
btnImportKey.setEnabled(security.resolveActivity(pm) != null); btnImportKey.setEnabled(security.resolveActivity(pm) != null); // system whitelisted
btnManageKeys.setOnClickListener(new View.OnClickListener() { btnManageKeys.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {

@ -310,7 +310,6 @@ public class FragmentOptionsMisc extends FragmentBase implements SharedPreferenc
final Intent app = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); final Intent app = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
app.setData(Uri.parse("package:" + getContext().getPackageName())); app.setData(Uri.parse("package:" + getContext().getPackageName()));
btnApp.setEnabled(app.resolveActivity(getContext().getPackageManager()) != null);
btnApp.setOnClickListener(new View.OnClickListener() { btnApp.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {

@ -157,7 +157,7 @@ public class FragmentOptionsNotifications extends FragmentBase implements Shared
.putExtra("app_uid", getContext().getApplicationInfo().uid) .putExtra("app_uid", getContext().getApplicationInfo().uid)
.putExtra(Settings.EXTRA_APP_PACKAGE, getContext().getPackageName()); .putExtra(Settings.EXTRA_APP_PACKAGE, getContext().getPackageName());
btnManage.setEnabled(manage.resolveActivity(pm) != null); btnManage.setEnabled(manage.resolveActivity(pm) != null); // system whitelisted
btnManage.setOnClickListener(new View.OnClickListener() { btnManage.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View view) { public void onClick(View view) {
@ -169,7 +169,7 @@ public class FragmentOptionsNotifications extends FragmentBase implements Shared
.putExtra(Settings.EXTRA_APP_PACKAGE, getContext().getPackageName()) .putExtra(Settings.EXTRA_APP_PACKAGE, getContext().getPackageName())
.putExtra(Settings.EXTRA_CHANNEL_ID, "notification"); .putExtra(Settings.EXTRA_CHANNEL_ID, "notification");
btnManageDefault.setEnabled(channelNotification.resolveActivity(pm) != null); btnManageDefault.setEnabled(channelNotification.resolveActivity(pm) != null); // system whitelisted
btnManageDefault.setOnClickListener(new View.OnClickListener() { btnManageDefault.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View view) { public void onClick(View view) {
@ -181,7 +181,7 @@ public class FragmentOptionsNotifications extends FragmentBase implements Shared
.putExtra(Settings.EXTRA_APP_PACKAGE, getContext().getPackageName()) .putExtra(Settings.EXTRA_APP_PACKAGE, getContext().getPackageName())
.putExtra(Settings.EXTRA_CHANNEL_ID, "service"); .putExtra(Settings.EXTRA_CHANNEL_ID, "service");
btnManageService.setEnabled(channelService.resolveActivity(pm) != null); btnManageService.setEnabled(channelService.resolveActivity(pm) != null); // system whitelisted
btnManageService.setOnClickListener(new View.OnClickListener() { btnManageService.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View view) { public void onClick(View view) {

@ -23,6 +23,7 @@ import android.app.Dialog;
import android.app.TimePickerDialog; import android.app.TimePickerDialog;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor; import android.database.Cursor;
import android.graphics.Color; import android.graphics.Color;
import android.net.Uri; import android.net.Uri;
@ -261,7 +262,8 @@ public class FragmentRule extends FragmentBase {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
Intent pick = new Intent(Intent.ACTION_PICK, ContactsContract.CommonDataKinds.Email.CONTENT_URI); Intent pick = new Intent(Intent.ACTION_PICK, ContactsContract.CommonDataKinds.Email.CONTENT_URI);
if (pick.resolveActivity(getContext().getPackageManager()) == null) PackageManager pm = getContext().getPackageManager();
if (pick.resolveActivity(pm) == null) // system whitelisted
Snackbar.make(view, R.string.title_no_contacts, Snackbar.LENGTH_LONG).show(); Snackbar.make(view, R.string.title_no_contacts, Snackbar.LENGTH_LONG).show();
else else
startActivityForResult(Helper.getChooser(getContext(), pick), REQUEST_SENDER); startActivityForResult(Helper.getChooser(getContext(), pick), REQUEST_SENDER);
@ -281,7 +283,8 @@ public class FragmentRule extends FragmentBase {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
Intent pick = new Intent(Intent.ACTION_PICK, ContactsContract.CommonDataKinds.Email.CONTENT_URI); Intent pick = new Intent(Intent.ACTION_PICK, ContactsContract.CommonDataKinds.Email.CONTENT_URI);
if (pick.resolveActivity(getContext().getPackageManager()) == null) PackageManager pm = getContext().getPackageManager();
if (pick.resolveActivity(pm) == null) // system whitelisted
Snackbar.make(view, R.string.title_no_contacts, Snackbar.LENGTH_LONG).show(); Snackbar.make(view, R.string.title_no_contacts, Snackbar.LENGTH_LONG).show();
else else
startActivityForResult(Helper.getChooser(getContext(), pick), REQUEST_RECIPIENT); startActivityForResult(Helper.getChooser(getContext(), pick), REQUEST_RECIPIENT);

@ -274,7 +274,7 @@ public class FragmentSetup extends FragmentBase {
startActivity(settings); startActivity(settings);
} }
}); });
btnDataSaver.setEnabled(settings.resolveActivity(pm) != null); btnDataSaver.setEnabled(settings.resolveActivity(pm) != null); // system whitelisted
} }
btnInbox.setOnClickListener(new View.OnClickListener() { btnInbox.setOnClickListener(new View.OnClickListener() {
@ -408,7 +408,8 @@ public class FragmentSetup extends FragmentBase {
Boolean ignoring = true; Boolean ignoring = true;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
Intent intent = new Intent(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS); Intent intent = new Intent(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS);
if (intent.resolveActivity(getContext().getPackageManager()) != null) { PackageManager pm = getContext().getPackageManager();
if (intent.resolveActivity(pm) != null) { // system whitelisted
ignoring = Helper.isIgnoringOptimizations(getContext()); ignoring = Helper.isIgnoringOptimizations(getContext());
if (ignoring == null) if (ignoring == null)
ignoring = true; ignoring = true;

@ -350,10 +350,14 @@ public class Helper {
} }
static boolean hasCustomTabs(Context context, Uri uri) { static boolean hasCustomTabs(Context context, Uri uri) {
String scheme = (uri == null ? null : uri.getScheme());
if (!"http".equals(scheme) && !"https".equals(scheme))
return false;
PackageManager pm = context.getPackageManager(); PackageManager pm = context.getPackageManager();
Intent view = new Intent(Intent.ACTION_VIEW, uri); Intent view = new Intent(Intent.ACTION_VIEW, uri);
List<ResolveInfo> ris = pm.queryIntentActivities(view, 0); List<ResolveInfo> ris = pm.queryIntentActivities(view, 0); // action whitelisted
for (ResolveInfo info : ris) { for (ResolveInfo info : ris) {
Intent intent = new Intent(); Intent intent = new Intent();
intent.setAction(ACTION_CUSTOM_TABS_CONNECTION); intent.setAction(ACTION_CUSTOM_TABS_CONNECTION);
@ -407,11 +411,14 @@ public class Helper {
// View // View
static Intent getChooser(Context context, Intent intent) { static Intent getChooser(Context context, Intent intent) {
PackageManager pm = context.getPackageManager(); if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
if (pm.queryIntentActivities(intent, 0).size() == 1) PackageManager pm = context.getPackageManager();
if (pm.queryIntentActivities(intent, 0).size() == 1)
return intent;
else
return Intent.createChooser(intent, context.getString(R.string.title_select_app));
} else
return intent; return intent;
else
return Intent.createChooser(intent, context.getString(R.string.title_select_app));
} }
static void share(Context context, File file, String type, String name) { static void share(Context context, File file, String type, String name) {
@ -427,25 +434,39 @@ public class Helper {
intent.putExtra(Intent.EXTRA_TITLE, Helper.sanitizeFilename(name)); intent.putExtra(Intent.EXTRA_TITLE, Helper.sanitizeFilename(name));
Log.i("Intent=" + intent + " type=" + type); Log.i("Intent=" + intent + " type=" + type);
// Get targets if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
PackageManager pm = context.getPackageManager(); // Get targets
List<ResolveInfo> ris = pm.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY); PackageManager pm = context.getPackageManager();
for (ResolveInfo ri : ris) { List<ResolveInfo> ris = pm.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
Log.i("Target=" + ri); for (ResolveInfo ri : ris) {
context.grantUriPermission(ri.activityInfo.packageName, uri, Intent.FLAG_GRANT_READ_URI_PERMISSION); Log.i("Target=" + ri);
} context.grantUriPermission(ri.activityInfo.packageName, uri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
}
// Check if viewer available // Check if viewer available
if (ris.size() == 0) { if (ris.size() == 0) {
if ("application/ms-tnef".equals(type)) if ("application/ms-tnef".equals(type))
viewFAQ(context, 155); viewFAQ(context, 155);
else { else {
String message = context.getString(R.string.title_no_viewer, String message = context.getString(R.string.title_no_viewer,
type != null ? type : name != null ? name : file.getName()); type != null ? type : name != null ? name : file.getName());
ToastEx.makeText(context, message, Toast.LENGTH_LONG).show(); ToastEx.makeText(context, message, Toast.LENGTH_LONG).show();
}
} else
context.startActivity(intent);
} else {
try {
context.startActivity(intent);
} catch (ActivityNotFoundException ex) {
if ("application/ms-tnef".equals(type))
viewFAQ(context, 155);
else {
String message = context.getString(R.string.title_no_viewer,
type != null ? type : name != null ? name : file.getName());
ToastEx.makeText(context, message, Toast.LENGTH_LONG).show();
}
} }
} else }
context.startActivity(intent);
} }
static void view(Context context, Intent intent) { static void view(Context context, Intent intent) {
@ -453,7 +474,12 @@ public class Helper {
if ("http".equals(uri.getScheme()) || "https".equals(uri.getScheme())) if ("http".equals(uri.getScheme()) || "https".equals(uri.getScheme()))
view(context, intent.getData(), false); view(context, intent.getData(), false);
else else
context.startActivity(intent); try {
context.startActivity(intent);
} catch (ActivityNotFoundException ex) {
Log.w(ex);
ToastEx.makeText(context, context.getString(R.string.title_no_viewer, uri.toString()), Toast.LENGTH_LONG).show();
}
} }
static void view(Context context, Uri uri, boolean browse) { static void view(Context context, Uri uri, boolean browse) {
@ -554,10 +580,7 @@ public class Helper {
} }
static Intent getIntentRate(Context context) { static Intent getIntentRate(Context context) {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + BuildConfig.APPLICATION_ID)); return new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + BuildConfig.APPLICATION_ID));
if (intent.resolveActivity(context.getPackageManager()) == null)
intent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=" + BuildConfig.APPLICATION_ID));
return intent;
} }
static long getInstallTime(Context context) { static long getInstallTime(Context context) {

Loading…
Cancel
Save