Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open deep links in app, items already discovered (1st round) #3598

Open
wants to merge 16 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 26 additions & 8 deletions owncloudApp/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -80,24 +80,42 @@
<activity android:name=".presentation.ui.migration.StorageMigrationActivity" />
<activity
android:name=".ui.activity.SplashActivity"
android:theme="@style/Theme.ownCloud.Splash"
android:exported="true">
android:exported="true"
android:theme="@style/Theme.ownCloud.Splash">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".ui.activity.FileDisplayActivity"
android:exported="true"
android:theme="@style/Theme.ownCloud.Toolbar.Drawer"
android:windowSoftInputMode="adjustPan" />
android:windowSoftInputMode="adjustPan">
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />

<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />

<data
android:host="@string/deep_link_host"
android:pathPrefix="@string/deep_link_path_prefix"
android:scheme="https" />

<data
android:host="@string/deep_link_host"
android:pathPrefix="@string/deep_link_path_prefix"
android:scheme="http" />
</intent-filter>
</activity>
<activity android:name=".ui.activity.ManageAccountsActivity" />
<activity
android:name=".ui.activity.ReceiveExternalFilesActivity"
android:configChanges="orientation|screenSize"
android:excludeFromRecents="true"
android:taskAffinity=""
android:exported="true">
android:exported="true"
android:taskAffinity="">
<intent-filter>
<action android:name="android.intent.action.SEND" />

Expand Down Expand Up @@ -216,11 +234,11 @@
<activity android:name=".ui.activity.UploadPathActivity" />
<activity
android:name=".presentation.ui.sharing.ShareActivity"
android:exported="true"
android:label="@string/share_dialog_title"
android:launchMode="singleTop"
android:theme="@style/Theme.ownCloud"
android:windowSoftInputMode="adjustResize"
android:exported="true">
android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
Expand Down Expand Up @@ -259,4 +277,4 @@
</intent-filter>
</activity>
</application>
</manifest>
</manifest>
3 changes: 2 additions & 1 deletion owncloudApp/src/main/java/com/owncloud/android/MainApp.kt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/*
/**
* ownCloud Android client application
*
* @author masensio
Expand All @@ -7,6 +7,7 @@
* @author Christian Schabesberger
* @author David Crespo Ríos
* @author Juan Carlos Garrote Gascón
* @author Fernando Sanz Velasco
* Copyright (C) 2022 ownCloud GmbH.
*
* This program is free software: you can redistribute it and/or modify
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,6 @@ import java.io.FileOutputStream
import java.io.IOException
import java.io.InputStream
import java.io.OutputStream
import java.util.ArrayList
import java.util.HashSet
import java.util.Vector

class FileDataStorageManager {
Expand Down Expand Up @@ -311,6 +309,15 @@ class FileDataStorageManager {
return file
}

fun getFileByPrivateLink(privateLink: String): OCFile? {
val cursor = getFileCursorForValue(FILE_PRIVATE_LINK, privateLink) ?: return null
val file: OCFile? = if (cursor.moveToFirst()) {
createFileInstance(cursor)
} else null
cursor.close()
return file
}

fun fileExists(id: Long): Boolean = fileExists(_ID, id.toString())

fun fileExists(path: String): Boolean = fileExists(FILE_PATH, path)
Expand Down Expand Up @@ -1106,6 +1113,7 @@ class FileDataStorageManager {
isDownloading = it.getIntFromColumnOrThrow(FILE_IS_DOWNLOADING) == 1
etagInConflict = it.getStringFromColumnOrThrow(FILE_ETAG_IN_CONFLICT)
privateLink = it.getStringFromColumnOrThrow(FILE_PRIVATE_LINK)
owner = it.getStringFromColumnOrThrow(FILE_ACCOUNT_OWNER)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ public static AvailableOfflineStatus fromValue(int value) {
private boolean mSharedByLink;
private boolean mSharedWithSharee;
private String mPrivateLink;
private String mOwner;

/**
* URI to the local path of the file contents, if stored in the device; cached after first call
Expand All @@ -125,15 +126,15 @@ public static AvailableOfflineStatus fromValue(int value) {

/**
* Exportable URI to the local path of the file contents, if stored in the device.
*
* <p>
* Cached after first call, until changed.
*/
private Uri mExposedFileUri;
public static final String PRIVATE_LINK_PATH = "/index.php/f/";

/**
* Create new {@link OCFile} with given path.
*
* <p>
* The path received must be URL-decoded. Path separator must be File.separator, and it must be the first
* character in 'path'.
*
Expand Down Expand Up @@ -179,6 +180,7 @@ private OCFile(Parcel source) {
mEtagInConflict = source.readString();
mSharedWithSharee = source.readInt() == 1;
mPrivateLink = source.readString();
mOwner = source.readString();

}

Expand Down Expand Up @@ -206,6 +208,7 @@ public void writeToParcel(Parcel dest, int flags) {
dest.writeString(mEtagInConflict);
dest.writeInt(mSharedWithSharee ? 1 : 0);
dest.writeString(mPrivateLink);
dest.writeString(mOwner);
}

/**
Expand Down Expand Up @@ -352,7 +355,7 @@ public long getModificationTimestamp() {

/**
* Set a UNIX timestamp of the time the time the file was modified.
*
* <p>
* To update with the value returned by the server in every synchronization of the properties
* of this file.
*
Expand All @@ -374,7 +377,7 @@ public long getModificationTimestampAtLastSyncForData() {

/**
* Set a UNIX timestamp of the time the time the file was modified.
*
* <p>
* To update with the value returned by the server in every synchronization of THE CONTENTS
* of this file.
*
Expand All @@ -396,7 +399,7 @@ public String getFileName() {

/**
* Sets the name of the file
*
* <p>
* Does nothing if the new name is null, empty or includes "/" ; or if the file is the root
* directory
*/
Expand Down Expand Up @@ -507,6 +510,7 @@ public long getParentId() {

/**
* get remote path of parent file
*
* @return remote path
*/
public String getParentRemotePath() {
Expand Down Expand Up @@ -547,7 +551,7 @@ public AvailableOfflineStatus getAvailableOfflineStatus() {
}

/**
* @return 'True' when
* @return 'True' when
*/
public boolean isAvailableOffline() {
return (mAvailableOfflineStatus != AvailableOfflineStatus.NOT_AVAILABLE_OFFLINE);
Expand Down Expand Up @@ -651,8 +655,8 @@ public boolean isText() {
}

/**
* @param type Type to match in the file MIME type; it's MUST include the trailing "/"
* @return 'True' if the file MIME type matches the received parameter in the type part.
* @param type Type to match in the file MIME type; it's MUST include the trailing "/"
* @return 'True' if the file MIME type matches the received parameter in the type part.
*/
private boolean isOfType(String type) {
return (
Expand Down Expand Up @@ -750,4 +754,12 @@ public void copyLocalPropertiesFrom(OCFile sourceFile) {
setTreeEtag(sourceFile.getTreeEtag());
setEtagInConflict(sourceFile.getEtagInConflict());
}

public String getOwner() {
return mOwner;
}

public void setOwner(String owner) {
mOwner = (owner == null) ? "" : owner;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ public class FileActivity extends DrawerActivity
public static final String EXTRA_ACCOUNT = "com.owncloud.android.ui.activity.ACCOUNT";
public static final String EXTRA_FROM_NOTIFICATION =
"com.owncloud.android.ui.activity.FROM_NOTIFICATION";
public static final String EXTRA_ALREADY_HANDLED_DEEP_LINK =
"com.owncloud.android.ui.activity.ALREADY_HANDLED_DEEP_LINK";
public static final String EXTRA_FILE_LIST_OPTION = "EXTRA_FILE_LIST_OPTION";

private static final String KEY_WAITING_FOR_OP_ID = "WAITING_FOR_OP_ID";
Expand All @@ -98,6 +100,8 @@ public class FileActivity extends DrawerActivity
*/
private boolean mFromNotification;

private boolean mAlreadyHandledDeepLink = false;

/**
* Messages handler associated to the main thread and the life cycle of the activity
*/
Expand Down Expand Up @@ -131,6 +135,7 @@ protected void onCreate(Bundle savedInstanceState) {
if (savedInstanceState != null) {
mFile = savedInstanceState.getParcelable(FileActivity.EXTRA_FILE);
mFromNotification = savedInstanceState.getBoolean(FileActivity.EXTRA_FROM_NOTIFICATION);
mAlreadyHandledDeepLink = savedInstanceState.getBoolean(FileActivity.EXTRA_ALREADY_HANDLED_DEEP_LINK);
mFileOperationsHelper.setOpIdWaitingFor(
savedInstanceState.getLong(KEY_WAITING_FOR_OP_ID, Long.MAX_VALUE)
);
Expand Down Expand Up @@ -214,6 +219,7 @@ protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putParcelable(FileActivity.EXTRA_FILE, mFile);
outState.putBoolean(FileActivity.EXTRA_FROM_NOTIFICATION, mFromNotification);
outState.putBoolean(FileActivity.EXTRA_ALREADY_HANDLED_DEEP_LINK, mAlreadyHandledDeepLink);
outState.putLong(KEY_WAITING_FOR_OP_ID, mFileOperationsHelper.getOpIdWaitingFor());
if (getSupportActionBar() != null && getSupportActionBar().getTitle() != null) {
// Null check in case the actionbar is used in ActionBar.NAVIGATION_MODE_LIST
Expand Down Expand Up @@ -247,6 +253,14 @@ public boolean fromNotification() {
return mFromNotification;
}

public void setAlreadyHandledDeepLink(boolean alreadyHandledDeepLink) {
mAlreadyHandledDeepLink = alreadyHandledDeepLink;
}

public boolean isAlreadyHandledDeepLink() {
return mAlreadyHandledDeepLink;
}

public OperationsServiceBinder getOperationsServiceBinder() {
return mOperationsServiceBinder;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@
* @author Christian Schabesberger
* @author Shashvat Kedia
* @author Abel García de Prada
* @author Fernando Sanz Velasco
* Copyright (C) 2011 Bartek Przybylski
* Copyright (C) 2020 ownCloud GmbH.
* Copyright (C) 2022 ownCloud GmbH.
*
*
* This program is free software: you can redistribute it and/or modify
Expand Down Expand Up @@ -51,6 +52,7 @@ import com.owncloud.android.AppRater
import com.owncloud.android.BuildConfig
import com.owncloud.android.MainApp
import com.owncloud.android.R
import com.owncloud.android.authentication.AccountUtils
import com.owncloud.android.databinding.ActivityMainBinding
import com.owncloud.android.datamodel.FileDataStorageManager
import com.owncloud.android.datamodel.OCFile
Expand Down Expand Up @@ -225,6 +227,11 @@ class FileDisplayActivity : FileActivity(), FileFragment.ContainerActivity, OnEn
createMinFragments()
}

val dataIntent: Uri? = intent.data
dataIntent?.let {
handleDeepLink(dataIntent)
}

setBackgroundText()
}

Expand Down Expand Up @@ -415,7 +422,12 @@ class FileDisplayActivity : FileActivity(), FileFragment.ContainerActivity, OnEn

fun refreshListOfFilesFragment(reloadData: Boolean) {
val fileListFragment = listOfFilesFragment
fileListFragment?.listDirectory(reloadData)
if (intent.data == null || isAlreadyHandledDeepLink) {
fileListFragment?.listDirectory(reloadData)
} else {
fileListFragment?.listDirectory(getFileDiscovered(intent.data))
}

}

override fun onCreateOptionsMenu(menu: Menu): Boolean {
Expand Down Expand Up @@ -1647,6 +1659,47 @@ class FileDisplayActivity : FileActivity(), FileFragment.ContainerActivity, OnEn
manageOptionLockSelected(type)
}

private fun handleDeepLink(uri: Uri?) {
if (uri != null && AccountUtils.getAccounts(applicationContext).isEmpty()) {
showMessageInSnackbar(message = getString(R.string.no_account_configured))
} else if (uri != null && AccountUtils.getAccounts(applicationContext).size == 1) {
getFileDiscovered(uri).let { oCFile ->
if (oCFile != null) {
manageItem(oCFile)
} else {
showMessageInSnackbar(message = getString(R.string.no_file_found))
}
}
}
}

private fun getFileDiscovered(uri: Uri?): OCFile? {
return if (storageManager != null) {
storageManager.getFileByPrivateLink(uri.toString())
} else {
null
}
}

private fun manageItem(file: OCFile) {
onBrowsedDownTo(file)
setFile(file)
account = AccountUtils.getOwnCloudAccountByName(this, file.owner)

if (file.isFolder) {
refreshListOfFilesFragment(true)
return
}

if (PreviewImageFragment.canBePreviewed(file)) {
showDetails(file)
} else {
initFragmentsWithFile()
}

isAlreadyHandledDeepLink = true
}

companion object {
private const val TAG_LIST_OF_FILES = "LIST_OF_FILES"
private const val TAG_SECOND_FRAGMENT = "SECOND_FRAGMENT"
Expand Down
Loading