From 8987c4b777fcd808cdbb151a15ebf7c8c6986ead Mon Sep 17 00:00:00 2001 From: TrianguloY Date: Wed, 25 Nov 2020 12:25:49 +0100 Subject: [PATCH] CustomTabs toggleable button. CustomTabs empty service so other apps 'think' this can open custom tabs. --- app/src/main/AndroidManifest.xml | 10 +- .../urlchecker/modules/list/OpenModule.java | 71 ++++++++++++ .../urlchecker/services/CustomTabs.java | 105 ++++++++++++++++++ app/src/main/res/drawable/ctabs_off.xml | 20 ++++ app/src/main/res/drawable/ctabs_on.xml | 16 +++ app/src/main/res/layout/dialog_open.xml | 6 + 6 files changed, 227 insertions(+), 1 deletion(-) create mode 100644 app/src/main/java/com/trianguloy/urlchecker/services/CustomTabs.java create mode 100644 app/src/main/res/drawable/ctabs_off.xml create mode 100644 app/src/main/res/drawable/ctabs_on.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 6959eb1..0c91981 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -11,7 +11,7 @@ android:supportsRtl="true" android:theme="@android:style/Theme.DeviceDefault" android:usesCleartextTraffic="true"> - + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/trianguloy/urlchecker/modules/list/OpenModule.java b/app/src/main/java/com/trianguloy/urlchecker/modules/list/OpenModule.java index 0f0c2ce..47690e0 100644 --- a/app/src/main/java/com/trianguloy/urlchecker/modules/list/OpenModule.java +++ b/app/src/main/java/com/trianguloy/urlchecker/modules/list/OpenModule.java @@ -1,10 +1,13 @@ package com.trianguloy.urlchecker.modules.list; +import android.app.AlertDialog; import android.content.ClipData; import android.content.ClipboardManager; import android.content.Context; import android.content.Intent; import android.net.Uri; +import android.os.Build; +import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; import android.view.View; @@ -54,13 +57,17 @@ public class OpenModule extends AModuleData { class OpenDialog extends AModuleDialog implements View.OnClickListener, PopupMenu.OnMenuItemClickListener, View.OnLongClickListener { + private static final String CTABS_EXTRA = "android.support.customtabs.extra.SESSION"; + private LastOpened lastOpened; + private boolean ctabs = false; private List packages; private Button btn_open; private ImageButton btn_openWith; private Menu menu; private PopupMenu popup; + private ImageButton btn_ctabs; public OpenDialog(MainDialog dialog) { super(dialog); @@ -73,10 +80,22 @@ class OpenDialog extends AModuleDialog implements View.OnClickListener, PopupMen @Override public void onInitialize(View views) { + btn_ctabs = views.findViewById(R.id.ctabs); + btn_ctabs.setOnClickListener(this); + btn_ctabs.setOnLongClickListener(this); + setCtabs(getActivity().getIntent().hasExtra(CTABS_EXTRA)); + + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) { + btn_ctabs.setVisibility(View.GONE); + } + btn_open = views.findViewById(R.id.open); btn_open.setOnClickListener(this); + btn_open.setOnLongClickListener(this); + btn_openWith = views.findViewById(R.id.open_with); btn_openWith.setOnClickListener(this); + View btn_share = views.findViewById(R.id.share); btn_share.setOnClickListener(this); btn_share.setOnLongClickListener(this); @@ -99,6 +118,9 @@ class OpenDialog extends AModuleDialog implements View.OnClickListener, PopupMen @Override public void onClick(View v) { switch (v.getId()) { + case R.id.ctabs: + toggleCtabs(); + break; case R.id.open: openUrl(0); break; @@ -114,6 +136,12 @@ class OpenDialog extends AModuleDialog implements View.OnClickListener, PopupMen @Override public boolean onLongClick(View v) { switch (v.getId()) { + case R.id.ctabs: + Toast.makeText(getActivity(), "Toggle Custom Tabs feature", Toast.LENGTH_SHORT).show(); + break; + case R.id.open: + intentDetails(); + break; case R.id.share: copyToClipboard(); break; @@ -183,10 +211,29 @@ class OpenDialog extends AModuleDialog implements View.OnClickListener, PopupMen intent.setData(Uri.parse(getUrl())); intent.setComponent(null); intent.setPackage(chosed); + + } else { // replace with new VIEW intent intent = UrlUtilities.getViewIntent(getUrl(), chosed); } + + if (ctabs && !intent.hasExtra(CTABS_EXTRA)) { + // enable Custom tabs + + // https://developer.chrome.com/multidevice/android/customtabs + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { + Bundle extras = new Bundle(); + extras.putBinder(CTABS_EXTRA, null); // Set to null for no session + intent.putExtras(extras); + } + } + + if (!ctabs && intent.hasExtra(CTABS_EXTRA)) { + // disable ctabs + intent.removeExtra(CTABS_EXTRA); + } + getActivity().startActivity(intent); } @@ -223,4 +270,28 @@ class OpenDialog extends AModuleDialog implements View.OnClickListener, PopupMen Toast.makeText(getActivity(), R.string.mOpen_clipboard, Toast.LENGTH_LONG).show(); } } + + /** + * Toggle the custom tabs state + */ + private void toggleCtabs() { + setCtabs(!ctabs); + } + + /** + * Sets the custom tabs state + */ + private void setCtabs(boolean state) { + btn_ctabs.setImageResource(state ? R.drawable.ctabs_on : R.drawable.ctabs_off); + ctabs = state; + } + + /** + * Shows the uri of the current intent + */ + private void intentDetails() { + new AlertDialog.Builder(getActivity()) + .setMessage(getActivity().getIntent().toUri(0)) + .show(); + } } diff --git a/app/src/main/java/com/trianguloy/urlchecker/services/CustomTabs.java b/app/src/main/java/com/trianguloy/urlchecker/services/CustomTabs.java new file mode 100644 index 0000000..cc6e8e4 --- /dev/null +++ b/app/src/main/java/com/trianguloy/urlchecker/services/CustomTabs.java @@ -0,0 +1,105 @@ +package com.trianguloy.urlchecker.services; + +import android.app.Service; +import android.content.Intent; +import android.os.IBinder; +import android.util.Log; +import android.widget.Toast; + +import com.trianguloy.urlchecker.BuildConfig; + +/** + * Empty service for fake custom tabs. + *

+ * referrer: https://chromium.googlesource.com/chromium/src/+/b71e98cdf14f18cb967a73857826f6e8c568cea0/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnectionService.java + */ +public class CustomTabs extends Service { + + + @Override + public void onCreate() { + log("onCreate"); + super.onCreate(); + } + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + log("onStartCommand"); + return super.onStartCommand(intent, flags, startId); + } + + @Override + public void onDestroy() { + log("onDestroy"); + super.onDestroy(); + } + + @Override + public IBinder onBind(Intent intent) { + log("onBind"); + return null; +// return new IBinder() { +// @Override +// public String getInterfaceDescriptor() throws RemoteException { +// log("getInterfaceDescriptor"); +// return null; +// } +// +// @Override +// public boolean pingBinder() { +// log("pingBinder"); +// return false; +// } +// +// @Override +// public boolean isBinderAlive() { +// log("isBinderAlive"); +// return false; +// } +// +// @Override +// public IInterface queryLocalInterface(String descriptor) { +// log("queryLocalInterface"); +// return null; +// } +// +// @Override +// public void dump(FileDescriptor fd, String[] args) throws RemoteException { +// log("dump"); +// } +// +// @Override +// public void dumpAsync(FileDescriptor fd, String[] args) throws RemoteException { +// log("dumpAsync"); +// } +// +// @Override +// public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException { +// log("transact"); +// return false; +// } +// +// @Override +// public void linkToDeath(DeathRecipient recipient, int flags) throws RemoteException { +// log("linkToDeath"); +// } +// +// @Override +// public boolean unlinkToDeath(DeathRecipient recipient, int flags) { +// log("unlinkToDeath"); +// return false; +// } +// }; + } + + // ------------------- logging ------------------- + + private static final String TAG = "CT-service"; + + private void log(String message) { + if (BuildConfig.DEBUG) { + Toast.makeText(this, TAG + ": " + message, Toast.LENGTH_SHORT).show(); + } + Log.d(TAG, message); + } +} diff --git a/app/src/main/res/drawable/ctabs_off.xml b/app/src/main/res/drawable/ctabs_off.xml new file mode 100644 index 0000000..2eef6c4 --- /dev/null +++ b/app/src/main/res/drawable/ctabs_off.xml @@ -0,0 +1,20 @@ + + + + + + diff --git a/app/src/main/res/drawable/ctabs_on.xml b/app/src/main/res/drawable/ctabs_on.xml new file mode 100644 index 0000000..e41a936 --- /dev/null +++ b/app/src/main/res/drawable/ctabs_on.xml @@ -0,0 +1,16 @@ + + + + + diff --git a/app/src/main/res/layout/dialog_open.xml b/app/src/main/res/layout/dialog_open.xml index b20f01d..404125f 100644 --- a/app/src/main/res/layout/dialog_open.xml +++ b/app/src/main/res/layout/dialog_open.xml @@ -3,6 +3,12 @@ android:layout_width="match_parent" android:layout_height="wrap_content"> + +