├── .asf.yaml
├── .eslintrc.yml
├── .gitattributes
├── .github
├── ISSUE_TEMPLATE.md
├── ISSUE_TEMPLATE
│ ├── BUG_REPORT.md
│ ├── FEATURE_REQUEST.md
│ └── SUPPORT_QUESTION.md
├── PULL_REQUEST_TEMPLATE.md
└── workflows
│ ├── android.yml
│ ├── chrome.yml
│ ├── ios.yml
│ └── lint.yml
├── .gitignore
├── .jshintrc
├── .npmignore
├── .npmrc
├── .ratignore
├── CONTRIBUTING.md
├── LICENSE
├── NOTICE
├── README.md
├── RELEASENOTES.md
├── doc
└── plugins.md
├── package-lock.json
├── package.json
├── plugin.xml
├── src
├── android
│ ├── AssetFilesystem.java
│ ├── ContentFilesystem.java
│ ├── DirectoryManager.java
│ ├── EncodingException.java
│ ├── FileExistsException.java
│ ├── FileUtils.java
│ ├── Filesystem.java
│ ├── InvalidModificationException.java
│ ├── LocalFilesystem.java
│ ├── LocalFilesystemURL.java
│ ├── NoModificationAllowedException.java
│ ├── PendingRequests.java
│ ├── TypeMismatchException.java
│ └── build-extras.gradle
├── browser
│ └── FileProxy.js
├── ios
│ ├── CDVAssetLibraryFilesystem.h
│ ├── CDVAssetLibraryFilesystem.m
│ ├── CDVFile.bundle
│ │ └── PrivacyInfo.xcprivacy
│ ├── CDVFile.h
│ ├── CDVFile.m
│ ├── CDVLocalFilesystem.h
│ └── CDVLocalFilesystem.m
├── osx
│ ├── CDVFile.h
│ ├── CDVFile.m
│ ├── CDVLocalFilesystem.h
│ └── CDVLocalFilesystem.m
└── windows
│ └── FileProxy.js
├── tests
├── package-lock.json
├── package.json
├── plugin.xml
├── src
│ └── android
│ │ └── TestContentProvider.java
├── tests.js
└── www
│ └── fixtures
│ └── asset-test
│ └── asset-test.txt
├── types
└── index.d.ts
└── www
├── DirectoryEntry.js
├── DirectoryReader.js
├── Entry.js
├── File.js
├── FileEntry.js
├── FileError.js
├── FileReader.js
├── FileSystem.js
├── FileUploadOptions.js
├── FileUploadResult.js
├── FileWriter.js
├── Flags.js
├── LocalFileSystem.js
├── Metadata.js
├── ProgressEvent.js
├── android
├── Entry.js
└── FileSystem.js
├── browser
├── FileSystem.js
├── Preparing.js
└── isChrome.js
├── fileSystemPaths.js
├── fileSystems-roots.js
├── fileSystems.js
├── ios
├── Entry.js
└── FileSystem.js
├── osx
└── FileSystem.js
├── requestFileSystem.js
└── resolveLocalFileSystemURI.js
/.asf.yaml:
--------------------------------------------------------------------------------
1 | # Licensed to the Apache Software Foundation (ASF) under one
2 | # or more contributor license agreements. See the NOTICE file
3 | # distributed with this work for additional information
4 | # regarding copyright ownership. The ASF licenses this file
5 | # to you under the Apache License, Version 2.0 (the
6 | # "License"); you may not use this file except in compliance
7 | # with the License. You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing,
12 | # software distributed under the License is distributed on an
13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 | # KIND, either express or implied. See the License for the
15 | # specific language governing permissions and limitations
16 | # under the License.
17 |
18 | github:
19 | description: Apache Cordova File Plugin
20 | homepage: https://cordova.apache.org/
21 |
22 | labels:
23 | - android
24 | - cordova
25 | - hacktoberfest
26 | - ios
27 | - java
28 | - javascript
29 | - library
30 | - mobile
31 | - nodejs
32 | - objective-c
33 |
34 | features:
35 | wiki: false
36 | issues: true
37 | projects: true
38 |
39 | enabled_merge_buttons:
40 | squash: true
41 | merge: false
42 | rebase: false
43 |
44 | notifications:
45 | commits: commits@cordova.apache.org
46 | issues: issues@cordova.apache.org
47 | pullrequests_status: issues@cordova.apache.org
48 | pullrequests_comment: issues@cordova.apache.org
49 |
--------------------------------------------------------------------------------
/.eslintrc.yml:
--------------------------------------------------------------------------------
1 | root: true
2 | extends: '@cordova/eslint-config/browser'
3 | globals:
4 | cordova: true
5 | LocalFileSystem: true
6 | FileError: true
7 | DirectoryEntry: true
8 | FileWriter: true
9 | Flags: true
10 | Metadata: true
11 | FileSystem: true
12 | resolveLocalFileSystemURL: true
13 |
14 | overrides:
15 | - files: [tests/**/*.js]
16 | extends: '@cordova/eslint-config/node-tests'
17 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | * text eol=lf
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
1 |
5 |
6 | ### Issue Type
7 |
8 |
9 | - [ ] Bug Report
10 | - [ ] Feature Request
11 | - [ ] Support Question
12 |
13 | ## Description
14 |
15 | ## Information
16 |
17 |
18 | ### Command or Code
19 |
20 |
21 | ### Environment, Platform, Device
22 |
23 |
24 |
25 |
26 | ### Version information
27 |
34 |
35 |
36 |
37 | ## Checklist
38 |
39 |
40 | - [ ] I searched for already existing GitHub issues about this
41 | - [ ] I updated all Cordova tooling to their most recent version
42 | - [ ] I included all the necessary information above
43 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/BUG_REPORT.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: 🐛 Bug Report
3 | about: If something isn't working as expected.
4 |
5 | ---
6 |
7 | # Bug Report
8 |
9 | ## Problem
10 |
11 | ### What is expected to happen?
12 |
13 |
14 |
15 | ### What does actually happen?
16 |
17 |
18 |
19 | ## Information
20 |
21 |
22 |
23 |
24 | ### Command or Code
25 |
26 |
27 |
28 |
29 | ### Environment, Platform, Device
30 |
31 |
32 |
33 |
34 | ### Version information
35 |
42 |
43 |
44 |
45 | ## Checklist
46 |
47 |
48 | - [ ] I searched for existing GitHub issues
49 | - [ ] I updated all Cordova tooling to most recent version
50 | - [ ] I included all the necessary information above
51 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: 🚀 Feature Request
3 | about: A suggestion for a new functionality
4 |
5 | ---
6 |
7 | # Feature Request
8 |
9 | ## Motivation Behind Feature
10 |
11 |
12 |
13 |
14 | ## Feature Description
15 |
20 |
21 |
22 |
23 | ## Alternatives or Workarounds
24 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/SUPPORT_QUESTION.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: 💬 Support Question
3 | about: If you have a question, please check out our Slack or StackOverflow!
4 |
5 | ---
6 |
7 |
8 |
9 | Apache Cordova uses GitHub Issues as a feature request and bug tracker _only_.
10 | For usage and support questions, please check out the resources below. Thanks!
11 |
12 | ---
13 |
14 | You can get answers to your usage and support questions about **Apache Cordova** on:
15 |
16 | * Slack Community Chat: https://cordova.slack.com (you can sign-up at http://slack.cordova.io/)
17 | * StackOverflow: https://stackoverflow.com/questions/tagged/cordova using the tag `cordova`
18 |
19 | ---
20 |
21 | If you are using a tool that uses Cordova internally, like e.g. Ionic, check their support channels:
22 |
23 | * **Ionic Framework**
24 | * [Ionic Community Forum](https://forum.ionicframework.com/)
25 | * [Ionic Worldwide Slack](https://ionicworldwide.herokuapp.com/)
26 | * **PhoneGap**
27 | * [PhoneGap Developer Community](https://forums.adobe.com/community/phonegap)
28 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 |
8 |
9 | ### Platforms affected
10 |
11 |
12 |
13 | ### Motivation and Context
14 |
15 |
16 |
17 |
18 |
19 | ### Description
20 |
21 |
22 |
23 |
24 | ### Testing
25 |
26 |
27 |
28 |
29 | ### Checklist
30 |
31 | - [ ] I've run the tests to see all new and existing tests pass
32 | - [ ] I added automated test coverage as appropriate for this change
33 | - [ ] Commit is prefixed with `(platform)` if this change only applies to one platform (e.g. `(android)`)
34 | - [ ] If this Pull Request resolves an issue, I linked to the issue in the text above (and used the correct [keyword to close issues using keywords](https://help.github.com/articles/closing-issues-using-keywords/))
35 | - [ ] I've updated the documentation if necessary
36 |
--------------------------------------------------------------------------------
/.github/workflows/android.yml:
--------------------------------------------------------------------------------
1 | # Licensed to the Apache Software Foundation (ASF) under one
2 | # or more contributor license agreements. See the NOTICE file
3 | # distributed with this work for additional information
4 | # regarding copyright ownership. The ASF licenses this file
5 | # to you under the Apache License, Version 2.0 (the
6 | # "License"); you may not use this file except in compliance
7 | # with the License. You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing,
12 | # software distributed under the License is distributed on an
13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 | # KIND, either express or implied. See the License for the
15 | # specific language governing permissions and limitations
16 | # under the License.
17 |
18 | name: Android Testsuite
19 |
20 | on:
21 | push:
22 | paths-ignore:
23 | - '**.md'
24 | - 'LICENSE'
25 | - '.eslint*'
26 |
27 | pull_request:
28 | paths-ignore:
29 | - '**.md'
30 | - 'LICENSE'
31 | - '.eslint*'
32 |
33 | jobs:
34 | test:
35 | name: Android ${{ matrix.versions.android }} Test
36 | runs-on: ubuntu-latest
37 | continue-on-error: true
38 |
39 | # hoist configurations to top that are expected to be updated
40 | env:
41 | # Storing a copy of the repo
42 | repo: ${{ github.event.pull_request.head.repo.full_name || github.repository }}
43 |
44 | node-version: 20
45 |
46 | # These are the default Java configurations used by most tests.
47 | # To customize these options, add "java-distro" or "java-version" to the strategy matrix with its overriding value.
48 | default_java-distro: temurin
49 | default_java-version: 17
50 |
51 | # These are the default Android System Image configurations used by most tests.
52 | # To customize these options, add "system-image-arch" or "system-image-target" to the strategy matrix with its overriding value.
53 | default_system-image-arch: x86_64
54 | default_system-image-target: google_apis # Most system images have a google_api option. Set this as default.
55 |
56 | # configurations for each testing strategy (test matrix)
57 | strategy:
58 | matrix:
59 | versions:
60 | - android: 7
61 | android-api: 24
62 |
63 | - android: 7.1
64 | android-api: 25
65 |
66 | - android: 8
67 | android-api: 26
68 |
69 | - android: 8.1
70 | android-api: 27
71 | system-image-arch: x86
72 |
73 | - android: 9
74 | android-api: 28
75 |
76 | - android: 10
77 | android-api: 29
78 |
79 | - android: 11
80 | android-api: 30
81 |
82 | - android: 12
83 | android-api: 31
84 |
85 | - android: 12L
86 | android-api: 32
87 |
88 | - android: 13
89 | android-api: 33
90 |
91 | - android: 14
92 | android-api: 34
93 |
94 | timeout-minutes: 60
95 |
96 | steps:
97 | - uses: actions/checkout@v4
98 | - uses: actions/setup-node@v4
99 | with:
100 | node-version: ${{ env.node-version }}
101 | - uses: actions/setup-java@v4
102 | env:
103 | java-version: ${{ matrix.versions.java-version == '' && env.default_java-version || matrix.versions.java-version }}
104 | java-distro: ${{ matrix.versions.java-distro == '' && env.default_java-distro || matrix.versions.java-distro }}
105 | with:
106 | distribution: ${{ env.java-distro }}
107 | java-version: ${{ env.java-version }}
108 |
109 | - name: Enable KVM group perms
110 | run: |
111 | echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
112 | sudo udevadm control --reload-rules
113 | sudo udevadm trigger --name-match=kvm
114 |
115 | - name: Run Environment Information
116 | run: |
117 | node --version
118 | npm --version
119 | java -version
120 |
121 | - name: Run npm install
122 | run: |
123 | export PATH="/usr/local/lib/android/sdk/platform-tools":$PATH
124 | export JAVA_HOME=$JAVA_HOME_11_X64
125 | npm i -g cordova@latest
126 | npm ci
127 |
128 | - name: Run paramedic install
129 | if: ${{ endswith(env.repo, '/cordova-paramedic') != true }}
130 | run: npm i -g github:apache/cordova-paramedic
131 |
132 | - uses: reactivecircus/android-emulator-runner@v2
133 | env:
134 | system-image-arch: ${{ matrix.versions.system-image-arch == '' && env.default_system-image-arch || matrix.versions.system-image-arch }}
135 | system-image-target: ${{ matrix.versions.system-image-target == '' && env.default_system-image-target || matrix.versions.system-image-target }}
136 | with:
137 | api-level: ${{ matrix.versions.android-api }}
138 | target: ${{ env.system-image-target }}
139 | arch: ${{ env.system-image-arch }}
140 | force-avd-creation: false
141 | disable-animations: false
142 | emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim
143 | script: echo "Pregenerate the AVD before running Paramedic"
144 |
145 | - name: Run paramedic tests
146 | uses: reactivecircus/android-emulator-runner@v2
147 | env:
148 | system-image-arch: ${{ matrix.versions.system-image-arch == '' && env.default_system-image-arch || matrix.versions.system-image-arch }}
149 | system-image-target: ${{ matrix.versions.system-image-target == '' && env.default_system-image-target || matrix.versions.system-image-target }}
150 | test_config: 'android-${{ matrix.versions.android }}.config.json'
151 | # Generally, this should automatically work for cordova-paramedic & plugins. If the path is unique, this can be manually changed.
152 | test_plugin_path: ${{ endswith(env.repo, '/cordova-paramedic') && './spec/testable-plugin/' || './' }}
153 | paramedic: ${{ endswith(env.repo, '/cordova-paramedic') && 'node main.js' || 'cordova-paramedic' }}
154 | with:
155 | api-level: ${{ matrix.versions.android-api }}
156 | target: ${{ env.system-image-target }}
157 | arch: ${{ env.system-image-arch }}
158 | force-avd-creation: false
159 | disable-animations: false
160 | emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim
161 | script: ${{ env.paramedic }} --config ./pr/local/${{ env.test_config }} --plugin ${{ env.test_plugin_path }}
162 |
--------------------------------------------------------------------------------
/.github/workflows/chrome.yml:
--------------------------------------------------------------------------------
1 | # Licensed to the Apache Software Foundation (ASF) under one
2 | # or more contributor license agreements. See the NOTICE file
3 | # distributed with this work for additional information
4 | # regarding copyright ownership. The ASF licenses this file
5 | # to you under the Apache License, Version 2.0 (the
6 | # "License"); you may not use this file except in compliance
7 | # with the License. You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing,
12 | # software distributed under the License is distributed on an
13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 | # KIND, either express or implied. See the License for the
15 | # specific language governing permissions and limitations
16 | # under the License.
17 |
18 | name: Chrome Testsuite
19 |
20 | on:
21 | push:
22 | paths-ignore:
23 | - '**.md'
24 | - 'LICENSE'
25 | - '.eslint*'
26 | pull_request:
27 | paths-ignore:
28 | - '**.md'
29 | - 'LICENSE'
30 | - '.eslint*'
31 |
32 | jobs:
33 | test:
34 | name: Chrome Latest Test
35 | runs-on: ubuntu-latest
36 |
37 | # hoist configurations to top that are expected to be updated
38 | env:
39 | # Storing a copy of the repo
40 | repo: ${{ github.event.pull_request.head.repo.full_name || github.repository }}
41 |
42 | node-version: 20
43 |
44 | steps:
45 | - uses: actions/checkout@v4
46 | - uses: actions/setup-node@v4
47 | with:
48 | node-version: ${{ env.node-version }}
49 |
50 | - name: Run install xvfb
51 | run: sudo apt-get install xvfb
52 |
53 | - name: Run Environment Information
54 | run: |
55 | node --version
56 | npm --version
57 |
58 | - name: Run npm install
59 | run: |
60 | npm i -g cordova@latest
61 | npm ci
62 |
63 | - name: Run paramedic install
64 | if: ${{ endswith(env.repo, '/cordova-paramedic') != true }}
65 | run: npm i -g github:apache/cordova-paramedic
66 |
67 | - name: Run paramedic tests
68 | env:
69 | test_config: 'browser.config.json'
70 | # Generally, this should automatically work for cordova-paramedic & plugins. If the path is unique, this can be manually changed.
71 | test_plugin_path: ${{ endswith(env.repo, '/cordova-paramedic') && './spec/testable-plugin/' || './' }}
72 | paramedic: ${{ endswith(env.repo, '/cordova-paramedic') && 'node main.js' || 'cordova-paramedic' }}
73 | run: xvfb-run --auto-servernum ${{ env.paramedic }} --config ./pr/local/${{ env.test_config }} --plugin ${{ env.test_plugin_path }}
74 |
--------------------------------------------------------------------------------
/.github/workflows/ios.yml:
--------------------------------------------------------------------------------
1 | # Licensed to the Apache Software Foundation (ASF) under one
2 | # or more contributor license agreements. See the NOTICE file
3 | # distributed with this work for additional information
4 | # regarding copyright ownership. The ASF licenses this file
5 | # to you under the Apache License, Version 2.0 (the
6 | # "License"); you may not use this file except in compliance
7 | # with the License. You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing,
12 | # software distributed under the License is distributed on an
13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 | # KIND, either express or implied. See the License for the
15 | # specific language governing permissions and limitations
16 | # under the License.
17 |
18 | name: iOS Testsuite
19 |
20 | on:
21 | push:
22 | paths-ignore:
23 | - '**.md'
24 | - 'LICENSE'
25 | - '.eslint*'
26 | pull_request:
27 | paths-ignore:
28 | - '**.md'
29 | - 'LICENSE'
30 | - '.eslint*'
31 |
32 | jobs:
33 | test:
34 | name: iOS ${{ matrix.versions.ios-version }} Test
35 | runs-on: ${{ matrix.versions.os-version }}
36 | continue-on-error: true
37 |
38 | # hoist configurations to top that are expected to be updated
39 | env:
40 | # Storing a copy of the repo
41 | repo: ${{ github.event.pull_request.head.repo.full_name || github.repository }}
42 |
43 | node-version: 20
44 |
45 | # > Starting April 26, 2021, all iOS and iPadOS apps submitted to the App Store must be built with Xcode 12 and the iOS 14 SDK.
46 | # Because of Apple's requirement, listed above, We will only be using the latest Xcode release for testing.
47 | # To customize these options, add "xcode-version" to the strategy matrix with its overriding value.
48 | default_xcode-version: latest-stable
49 |
50 | strategy:
51 | matrix:
52 | versions:
53 | - os-version: macos-12
54 | ios-version: 15.x
55 | xcode-version: 13.x
56 |
57 | - os-version: macos-14
58 | ios-version: 16.x
59 | xcode-version: 14.x
60 |
61 | - os-version: macos-14
62 | ios-version: 17.x
63 | xcode-version: 15.x
64 |
65 | steps:
66 | - uses: actions/checkout@v4
67 | - uses: actions/setup-node@v4
68 | with:
69 | node-version: ${{ env.node-version }}
70 | - uses: maxim-lobanov/setup-xcode@60606e260d2fc5762a71e64e74b2174e8ea3c8bd
71 | env:
72 | xcode-version: ${{ matrix.versions.xcode-version == '' && env.default_xcode-version || matrix.versions.xcode-version }}
73 | with:
74 | xcode-version: ${{ env.xcode-version }}
75 |
76 | - name: Run Environment Information
77 | run: |
78 | node --version
79 | npm --version
80 | xcodebuild -version
81 |
82 | - name: Run npm install
83 | run: |
84 | npm i -g cordova@latest ios-deploy@latest
85 | npm ci
86 |
87 | - name: Run paramedic install
88 | if: ${{ endswith(env.repo, '/cordova-paramedic') != true }}
89 | run: npm i -g github:apache/cordova-paramedic
90 |
91 | - name: Run paramedic tests
92 | env:
93 | test_config: 'ios-${{ matrix.versions.ios-version }}.config.json'
94 | # Generally, this should automatically work for cordova-paramedic & plugins. If the path is unique, this can be manually changed.
95 | test_plugin_path: ${{ endswith(env.repo, '/cordova-paramedic') && './spec/testable-plugin/' || './' }}
96 | paramedic: ${{ endswith(env.repo, '/cordova-paramedic') && 'node main.js' || 'cordova-paramedic' }}
97 | run: ${{ env.paramedic }} --config ./pr/local/${{ env.test_config }} --plugin ${{ env.test_plugin_path }}
98 |
--------------------------------------------------------------------------------
/.github/workflows/lint.yml:
--------------------------------------------------------------------------------
1 | # Licensed to the Apache Software Foundation (ASF) under one
2 | # or more contributor license agreements. See the NOTICE file
3 | # distributed with this work for additional information
4 | # regarding copyright ownership. The ASF licenses this file
5 | # to you under the Apache License, Version 2.0 (the
6 | # "License"); you may not use this file except in compliance
7 | # with the License. You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing,
12 | # software distributed under the License is distributed on an
13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 | # KIND, either express or implied. See the License for the
15 | # specific language governing permissions and limitations
16 | # under the License.
17 |
18 | name: Lint Test
19 |
20 | on:
21 | push:
22 | paths:
23 | - '**.js'
24 | - '.eslint*'
25 | - '.github/workflow/lint.yml'
26 | pull_request:
27 | paths:
28 | - '**.js'
29 | - '.eslint*'
30 | - '.github/workflow/lint.yml'
31 |
32 | jobs:
33 | test:
34 | name: Lint Test
35 | runs-on: ubuntu-latest
36 | env:
37 | node-version: 20
38 |
39 | steps:
40 | - uses: actions/checkout@v4
41 | - uses: actions/setup-node@v4
42 | with:
43 | node-version: ${{ env.node-version }}
44 |
45 | - name: Run Environment Information
46 | run: |
47 | node --version
48 | npm --version
49 |
50 | - name: Run npm install
51 | run: |
52 | npm ci
53 |
54 | - name: Run lint test
55 | run: |
56 | npm run lint
57 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | #If ignorance is bliss, then somebody knock the smile off my face
2 |
3 | *.csproj.user
4 | *.suo
5 | *.cache
6 | Thumbs.db
7 | *.DS_Store
8 |
9 | *.bak
10 | *.cache
11 | *.log
12 | *.swp
13 | *.user
14 |
15 | /.project
16 | node_modules
17 |
--------------------------------------------------------------------------------
/.jshintrc:
--------------------------------------------------------------------------------
1 | {
2 | "browser": true
3 | , "devel": true
4 | , "bitwise": true
5 | , "undef": true
6 | , "trailing": true
7 | , "quotmark": false
8 | , "indent": 4
9 | , "unused": "vars"
10 | , "latedef": "nofunc"
11 | , "globals": {
12 | "module": false,
13 | "exports": false,
14 | "require": false,
15 | "cordova": false,
16 | "File": true,
17 | "FileSystem": true,
18 | "FileReader": true,
19 | "FileWriter": true,
20 | "FileError": true,
21 | "LocalFileSystem": true,
22 | "Metadata": true,
23 | "Flags": true,
24 | "DirectoryEntry": true,
25 | "resolveLocalFileSystemURL": false,
26 | "requestFileSystem": true,
27 | "FILESYSTEM_PREFIX": true,
28 | "FILESYSTEM_PROTOCOL": true
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | .*
2 | tests
3 |
--------------------------------------------------------------------------------
/.npmrc:
--------------------------------------------------------------------------------
1 | registry=https://registry.npmjs.org
2 |
3 |
--------------------------------------------------------------------------------
/.ratignore:
--------------------------------------------------------------------------------
1 | asset-test.txt
2 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 |
21 |
22 | # Contributing to Apache Cordova
23 |
24 | Anyone can contribute to Cordova. And we need your contributions.
25 |
26 | There are multiple ways to contribute: report bugs, improve the docs, and
27 | contribute code.
28 |
29 | For instructions on this, start with the
30 | [contribution overview](http://cordova.apache.org/contribute/).
31 |
32 | The details are explained there, but the important items are:
33 | - Check for Github issues that corresponds to your contribution and link or create them if necessary.
34 | - Run the tests so your patch doesn't break existing functionality.
35 |
36 | We look forward to your contributions!
37 |
38 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 |
2 | Apache License
3 | Version 2.0, January 2004
4 | http://www.apache.org/licenses/
5 |
6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7 |
8 | 1. Definitions.
9 |
10 | "License" shall mean the terms and conditions for use, reproduction,
11 | and distribution as defined by Sections 1 through 9 of this document.
12 |
13 | "Licensor" shall mean the copyright owner or entity authorized by
14 | the copyright owner that is granting the License.
15 |
16 | "Legal Entity" shall mean the union of the acting entity and all
17 | other entities that control, are controlled by, or are under common
18 | control with that entity. For the purposes of this definition,
19 | "control" means (i) the power, direct or indirect, to cause the
20 | direction or management of such entity, whether by contract or
21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
22 | outstanding shares, or (iii) beneficial ownership of such entity.
23 |
24 | "You" (or "Your") shall mean an individual or Legal Entity
25 | exercising permissions granted by this License.
26 |
27 | "Source" form shall mean the preferred form for making modifications,
28 | including but not limited to software source code, documentation
29 | source, and configuration files.
30 |
31 | "Object" form shall mean any form resulting from mechanical
32 | transformation or translation of a Source form, including but
33 | not limited to compiled object code, generated documentation,
34 | and conversions to other media types.
35 |
36 | "Work" shall mean the work of authorship, whether in Source or
37 | Object form, made available under the License, as indicated by a
38 | copyright notice that is included in or attached to the work
39 | (an example is provided in the Appendix below).
40 |
41 | "Derivative Works" shall mean any work, whether in Source or Object
42 | form, that is based on (or derived from) the Work and for which the
43 | editorial revisions, annotations, elaborations, or other modifications
44 | represent, as a whole, an original work of authorship. For the purposes
45 | of this License, Derivative Works shall not include works that remain
46 | separable from, or merely link (or bind by name) to the interfaces of,
47 | the Work and Derivative Works thereof.
48 |
49 | "Contribution" shall mean any work of authorship, including
50 | the original version of the Work and any modifications or additions
51 | to that Work or Derivative Works thereof, that is intentionally
52 | submitted to Licensor for inclusion in the Work by the copyright owner
53 | or by an individual or Legal Entity authorized to submit on behalf of
54 | the copyright owner. For the purposes of this definition, "submitted"
55 | means any form of electronic, verbal, or written communication sent
56 | to the Licensor or its representatives, including but not limited to
57 | communication on electronic mailing lists, source code control systems,
58 | and issue tracking systems that are managed by, or on behalf of, the
59 | Licensor for the purpose of discussing and improving the Work, but
60 | excluding communication that is conspicuously marked or otherwise
61 | designated in writing by the copyright owner as "Not a Contribution."
62 |
63 | "Contributor" shall mean Licensor and any individual or Legal Entity
64 | on behalf of whom a Contribution has been received by Licensor and
65 | subsequently incorporated within the Work.
66 |
67 | 2. Grant of Copyright License. Subject to the terms and conditions of
68 | this License, each Contributor hereby grants to You a perpetual,
69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70 | copyright license to reproduce, prepare Derivative Works of,
71 | publicly display, publicly perform, sublicense, and distribute the
72 | Work and such Derivative Works in Source or Object form.
73 |
74 | 3. Grant of Patent License. Subject to the terms and conditions of
75 | this License, each Contributor hereby grants to You a perpetual,
76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77 | (except as stated in this section) patent license to make, have made,
78 | use, offer to sell, sell, import, and otherwise transfer the Work,
79 | where such license applies only to those patent claims licensable
80 | by such Contributor that are necessarily infringed by their
81 | Contribution(s) alone or by combination of their Contribution(s)
82 | with the Work to which such Contribution(s) was submitted. If You
83 | institute patent litigation against any entity (including a
84 | cross-claim or counterclaim in a lawsuit) alleging that the Work
85 | or a Contribution incorporated within the Work constitutes direct
86 | or contributory patent infringement, then any patent licenses
87 | granted to You under this License for that Work shall terminate
88 | as of the date such litigation is filed.
89 |
90 | 4. Redistribution. You may reproduce and distribute copies of the
91 | Work or Derivative Works thereof in any medium, with or without
92 | modifications, and in Source or Object form, provided that You
93 | meet the following conditions:
94 |
95 | (a) You must give any other recipients of the Work or
96 | Derivative Works a copy of this License; and
97 |
98 | (b) You must cause any modified files to carry prominent notices
99 | stating that You changed the files; and
100 |
101 | (c) You must retain, in the Source form of any Derivative Works
102 | that You distribute, all copyright, patent, trademark, and
103 | attribution notices from the Source form of the Work,
104 | excluding those notices that do not pertain to any part of
105 | the Derivative Works; and
106 |
107 | (d) If the Work includes a "NOTICE" text file as part of its
108 | distribution, then any Derivative Works that You distribute must
109 | include a readable copy of the attribution notices contained
110 | within such NOTICE file, excluding those notices that do not
111 | pertain to any part of the Derivative Works, in at least one
112 | of the following places: within a NOTICE text file distributed
113 | as part of the Derivative Works; within the Source form or
114 | documentation, if provided along with the Derivative Works; or,
115 | within a display generated by the Derivative Works, if and
116 | wherever such third-party notices normally appear. The contents
117 | of the NOTICE file are for informational purposes only and
118 | do not modify the License. You may add Your own attribution
119 | notices within Derivative Works that You distribute, alongside
120 | or as an addendum to the NOTICE text from the Work, provided
121 | that such additional attribution notices cannot be construed
122 | as modifying the License.
123 |
124 | You may add Your own copyright statement to Your modifications and
125 | may provide additional or different license terms and conditions
126 | for use, reproduction, or distribution of Your modifications, or
127 | for any such Derivative Works as a whole, provided Your use,
128 | reproduction, and distribution of the Work otherwise complies with
129 | the conditions stated in this License.
130 |
131 | 5. Submission of Contributions. Unless You explicitly state otherwise,
132 | any Contribution intentionally submitted for inclusion in the Work
133 | by You to the Licensor shall be under the terms and conditions of
134 | this License, without any additional terms or conditions.
135 | Notwithstanding the above, nothing herein shall supersede or modify
136 | the terms of any separate license agreement you may have executed
137 | with Licensor regarding such Contributions.
138 |
139 | 6. Trademarks. This License does not grant permission to use the trade
140 | names, trademarks, service marks, or product names of the Licensor,
141 | except as required for reasonable and customary use in describing the
142 | origin of the Work and reproducing the content of the NOTICE file.
143 |
144 | 7. Disclaimer of Warranty. Unless required by applicable law or
145 | agreed to in writing, Licensor provides the Work (and each
146 | Contributor provides its Contributions) on an "AS IS" BASIS,
147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148 | implied, including, without limitation, any warranties or conditions
149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150 | PARTICULAR PURPOSE. You are solely responsible for determining the
151 | appropriateness of using or redistributing the Work and assume any
152 | risks associated with Your exercise of permissions under this License.
153 |
154 | 8. Limitation of Liability. In no event and under no legal theory,
155 | whether in tort (including negligence), contract, or otherwise,
156 | unless required by applicable law (such as deliberate and grossly
157 | negligent acts) or agreed to in writing, shall any Contributor be
158 | liable to You for damages, including any direct, indirect, special,
159 | incidental, or consequential damages of any character arising as a
160 | result of this License or out of the use or inability to use the
161 | Work (including but not limited to damages for loss of goodwill,
162 | work stoppage, computer failure or malfunction, or any and all
163 | other commercial damages or losses), even if such Contributor
164 | has been advised of the possibility of such damages.
165 |
166 | 9. Accepting Warranty or Additional Liability. While redistributing
167 | the Work or Derivative Works thereof, You may choose to offer,
168 | and charge a fee for, acceptance of support, warranty, indemnity,
169 | or other liability obligations and/or rights consistent with this
170 | License. However, in accepting such obligations, You may act only
171 | on Your own behalf and on Your sole responsibility, not on behalf
172 | of any other Contributor, and only if You agree to indemnify,
173 | defend, and hold each Contributor harmless for any liability
174 | incurred by, or claims asserted against, such Contributor by reason
175 | of your accepting any such warranty or additional liability.
176 |
177 | END OF TERMS AND CONDITIONS
178 |
179 | APPENDIX: How to apply the Apache License to your work.
180 |
181 | To apply the Apache License to your work, attach the following
182 | boilerplate notice, with the fields enclosed by brackets "[]"
183 | replaced with your own identifying information. (Don't include
184 | the brackets!) The text should be enclosed in the appropriate
185 | comment syntax for the file format. We also recommend that a
186 | file or class name and description of purpose be included on the
187 | same "printed page" as the copyright notice for easier
188 | identification within third-party archives.
189 |
190 | Copyright [yyyy] [name of copyright owner]
191 |
192 | Licensed under the Apache License, Version 2.0 (the "License");
193 | you may not use this file except in compliance with the License.
194 | You may obtain a copy of the License at
195 |
196 | http://www.apache.org/licenses/LICENSE-2.0
197 |
198 | Unless required by applicable law or agreed to in writing, software
199 | distributed under the License is distributed on an "AS IS" BASIS,
200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
201 | See the License for the specific language governing permissions and
202 | limitations under the License.
--------------------------------------------------------------------------------
/NOTICE:
--------------------------------------------------------------------------------
1 | Apache Cordova
2 | Copyright 2012 The Apache Software Foundation
3 |
4 | This product includes software developed at
5 | The Apache Software Foundation (http://www.apache.org/).
6 |
--------------------------------------------------------------------------------
/doc/plugins.md:
--------------------------------------------------------------------------------
1 |
19 |
20 | Notes for plugin developers
21 | ===========================
22 |
23 | These notes are primarily intended for Android and iOS developers who want to write plugins which interface with the file system using the File plugin.
24 |
25 | Working with Cordova file system URLs
26 | -------------------------------------
27 |
28 | Since version 1.0.0, this plugin has used URLs with a `cdvfile` scheme for all communication over the bridge, rather than exposing raw device file system paths to JavaScript.
29 |
30 | On the JavaScript side, this means that FileEntry and DirectoryEntry objects have a fullPath attribute which is relative to the root of the HTML file system. If your plugin's JavaScript API accepts a FileEntry or DirectoryEntry object, you should call `.toURL()` on that object before passing it across the bridge to native code.
31 |
32 | ### Converting cdvfile:// URLs to fileystem paths
33 |
34 | Plugins which need to write to the filesystem may want to convert a received file system URL to an actual filesystem location. There are multiple ways of doing this, depending on the native platform.
35 |
36 | It is important to remember that not all `cdvfile://` URLs are mappable to real files on the device. Some URLs can refer to assets on device which are not represented by files, or can even refer to remote resources. Because of these possibilities, plugins should always test whether they get a meaningful result back when trying to convert URLs to paths.
37 |
38 | #### Android
39 |
40 | On Android, the simplest method to convert a `cdvfile://` URL to a filesystem path is to use `org.apache.cordova.CordovaResourceApi`. `CordovaResourceApi` has several methods which can handle `cdvfile://` URLs:
41 |
42 | // webView is a member of the Plugin class
43 | CordovaResourceApi resourceApi = webView.getResourceApi();
44 |
45 | // Obtain a file:/// URL representing this file on the device,
46 | // or the same URL unchanged if it cannot be mapped to a file
47 | Uri fileURL = resourceApi.remapUri(Uri.parse(cdvfileURL));
48 |
49 | It is also possible to use the File plugin directly:
50 |
51 | import org.apache.cordova.file.FileUtils;
52 | import org.apache.cordova.file.FileSystem;
53 | import java.net.MalformedURLException;
54 |
55 | // Get the File plugin from the plugin manager
56 | FileUtils filePlugin = (FileUtils)webView.pluginManager.getPlugin("File");
57 |
58 | // Given a URL, get a path for it
59 | try {
60 | String path = filePlugin.filesystemPathForURL(cdvfileURL);
61 | } catch (MalformedURLException e) {
62 | // The filesystem url wasn't recognized
63 | }
64 |
65 | To convert from a path to a `cdvfile://` URL:
66 |
67 | import org.apache.cordova.file.LocalFilesystemURL;
68 |
69 | // Get a LocalFilesystemURL object for a device path,
70 | // or null if it cannot be represented as a cdvfile URL.
71 | LocalFilesystemURL url = filePlugin.filesystemURLforLocalPath(path);
72 | // Get the string representation of the URL object
73 | String cdvfileURL = url.toString();
74 |
75 | If your plugin creates a file, and you want to return a FileEntry object for it, use the File plugin:
76 |
77 | // Return a JSON structure suitable for returning to JavaScript,
78 | // or null if this file is not representable as a cdvfile URL.
79 | JSONObject entry = filePlugin.getEntryForFile(file);
80 |
81 | #### iOS
82 |
83 | Cordova on iOS does not use the same `CordovaResourceApi` concept as Android. On iOS, you should use the File plugin to convert between URLs and filesystem paths.
84 |
85 | // Get a CDVFilesystem URL object from a URL string
86 | CDVFilesystemURL* url = [CDVFilesystemURL fileSystemURLWithString:cdvfileURL];
87 | // Get a path for the URL object, or nil if it cannot be mapped to a file
88 | NSString* path = [filePlugin filesystemPathForURL:url];
89 |
90 |
91 | // Get a CDVFilesystem URL object for a device path, or
92 | // nil if it cannot be represented as a cdvfile URL.
93 | CDVFilesystemURL* url = [filePlugin fileSystemURLforLocalPath:path];
94 | // Get the string representation of the URL object
95 | NSString* cdvfileURL = [url absoluteString];
96 |
97 | If your plugin creates a file, and you want to return a FileEntry object for it, use the File plugin:
98 |
99 | // Get a CDVFilesystem URL object for a device path, or
100 | // nil if it cannot be represented as a cdvfile URL.
101 | CDVFilesystemURL* url = [filePlugin fileSystemURLforLocalPath:path];
102 | // Get a structure to return to JavaScript
103 | NSDictionary* entry = [filePlugin makeEntryForLocalURL:url]
104 |
105 | #### JavaScript
106 |
107 | In JavaScript, to get a `cdvfile://` URL from a FileEntry or DirectoryEntry object, simply call `.toURL()` on it:
108 |
109 | var cdvfileURL = entry.toURL();
110 |
111 | In plugin response handlers, to convert from a returned FileEntry structure to an actual Entry object, your handler code should import the File plugin and create a new object:
112 |
113 | // create appropriate Entry object
114 | var entry;
115 | if (entryStruct.isDirectory) {
116 | entry = new DirectoryEntry(entryStruct.name, entryStruct.fullPath, new FileSystem(entryStruct.filesystemName));
117 | } else {
118 | entry = new FileEntry(entryStruct.name, entryStruct.fullPath, new FileSystem(entryStruct.filesystemName));
119 | }
120 |
121 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cordova-plugin-file",
3 | "version": "8.1.4-dev",
4 | "description": "Cordova File Plugin",
5 | "types": "./types/index.d.ts",
6 | "cordova": {
7 | "id": "cordova-plugin-file",
8 | "platforms": [
9 | "android",
10 | "browser",
11 | "ios",
12 | "osx",
13 | "windows"
14 | ]
15 | },
16 | "repository": "github:apache/cordova-plugin-file",
17 | "bugs": "https://github.com/apache/cordova-plugin-file/issues",
18 | "keywords": [
19 | "cordova",
20 | "file",
21 | "ecosystem:cordova",
22 | "cordova-android",
23 | "cordova-browser",
24 | "cordova-ios",
25 | "cordova-osx",
26 | "cordova-windows"
27 | ],
28 | "scripts": {
29 | "test": "npm run lint",
30 | "lint": "eslint ."
31 | },
32 | "author": "Apache Software Foundation",
33 | "license": "Apache-2.0",
34 | "engines": {
35 | "cordovaDependencies": {
36 | "5.0.0": {
37 | "cordova-android": ">=6.3.0"
38 | },
39 | "7.0.0": {
40 | "cordova-android": ">=10.0.0"
41 | },
42 | "8.0.0": {
43 | "cordova-android": ">=12.0.0"
44 | },
45 | "9.0.0": {
46 | "cordova": ">100"
47 | }
48 | }
49 | },
50 | "devDependencies": {
51 | "@cordova/eslint-config": "^5.0.0"
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/plugin.xml:
--------------------------------------------------------------------------------
1 |
2 |
20 |
21 |
25 | File
26 | Cordova File Plugin
27 | Apache 2.0
28 | cordova,file
29 | https://github.com/apache/cordova-plugin-file
30 | https://github.com/apache/cordova-plugin-file/issues
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 | The Android Persistent storage location now defaults to "Internal". Please check this plugin's README to see if your application needs any changes in its config.xml.
119 |
120 | If this is a new application no changes are required.
121 |
122 | If this is an update to an existing application that did not specify an "AndroidPersistentFileLocation" you may need to add:
123 |
124 | "<preference name="AndroidPersistentFileLocation" value="Compatibility" />"
125 |
126 | to config.xml in order for the application to find previously stored files.
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
--------------------------------------------------------------------------------
/src/android/ContentFilesystem.java:
--------------------------------------------------------------------------------
1 | /*
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. See the NOTICE file
4 | distributed with this work for additional information
5 | regarding copyright ownership. The ASF licenses this file
6 | to you under the Apache License, Version 2.0 (the
7 | "License"); you may not use this file except in compliance
8 | with the License. You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing,
13 | software distributed under the License is distributed on an
14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | KIND, either express or implied. See the License for the
16 | specific language governing permissions and limitations
17 | under the License.
18 | */
19 | package org.apache.cordova.file;
20 |
21 | import android.content.ContentResolver;
22 | import android.content.Context;
23 | import android.database.Cursor;
24 | import android.net.Uri;
25 | import android.provider.DocumentsContract;
26 | import android.provider.MediaStore;
27 | import android.provider.OpenableColumns;
28 | import java.io.File;
29 | import java.io.FileNotFoundException;
30 | import java.io.IOException;
31 |
32 | import org.apache.cordova.CordovaPreferences;
33 | import org.apache.cordova.CordovaResourceApi;
34 | import org.json.JSONException;
35 | import org.json.JSONObject;
36 |
37 | public class ContentFilesystem extends Filesystem {
38 |
39 | private final Context context;
40 |
41 | public ContentFilesystem(Context context, CordovaResourceApi resourceApi, CordovaPreferences preferences) {
42 | super(Uri.parse("content://"), "content", resourceApi, preferences);
43 | this.context = context;
44 | }
45 |
46 | @Override
47 | public Uri toNativeUri(LocalFilesystemURL inputURL) {
48 | String encodedPath = inputURL.uri.getEncodedPath();
49 | String authorityAndPath = encodedPath.substring(encodedPath.indexOf(this.name) + 1 + this.name.length() + 2);
50 | if (authorityAndPath.length() < 2) {
51 | return null;
52 | }
53 | String ret = "content://" + authorityAndPath;
54 | String query = inputURL.uri.getEncodedQuery();
55 | if (query != null) {
56 | ret += '?' + query;
57 | }
58 | String frag = inputURL.uri.getEncodedFragment();
59 | if (frag != null) {
60 | ret += '#' + frag;
61 | }
62 | return Uri.parse(ret);
63 | }
64 |
65 | @Override
66 | public LocalFilesystemURL toLocalUri(Uri inputURL) {
67 | if (!"content".equals(inputURL.getScheme())) {
68 | return null;
69 | }
70 | String subPath = inputURL.getEncodedPath();
71 | if (subPath.length() > 0) {
72 | subPath = subPath.substring(1);
73 | }
74 |
75 | Uri.Builder b = createLocalUriBuilder().appendPath(inputURL.getAuthority());
76 |
77 | if (subPath.length() > 0) {
78 | b.appendEncodedPath(subPath);
79 | }
80 | Uri localUri = b.encodedQuery(inputURL.getEncodedQuery())
81 | .encodedFragment(inputURL.getEncodedFragment())
82 | .build();
83 | return LocalFilesystemURL.parse(localUri);
84 | }
85 |
86 | @Override
87 | public JSONObject getFileForLocalURL(LocalFilesystemURL inputURL,
88 | String fileName, JSONObject options, boolean directory) throws IOException, TypeMismatchException, JSONException {
89 | throw new UnsupportedOperationException("getFile() not supported for content:. Use resolveLocalFileSystemURL instead.");
90 | }
91 |
92 | @Override
93 | public boolean removeFileAtLocalURL(LocalFilesystemURL inputURL)
94 | throws NoModificationAllowedException {
95 | Uri contentUri = toNativeUri(inputURL);
96 | try {
97 | context.getContentResolver().delete(contentUri, null, null);
98 | } catch (UnsupportedOperationException t) {
99 | // Was seeing this on the File mobile-spec tests on 4.0.3 x86 emulator.
100 | // The ContentResolver applies only when the file was registered in the
101 | // first case, which is generally only the case with images.
102 | NoModificationAllowedException nmae = new NoModificationAllowedException("Deleting not supported for content uri: " + contentUri);
103 | nmae.initCause(t);
104 | throw nmae;
105 | }
106 | return true;
107 | }
108 |
109 | @Override
110 | public boolean recursiveRemoveFileAtLocalURL(LocalFilesystemURL inputURL)
111 | throws NoModificationAllowedException {
112 | throw new NoModificationAllowedException("Cannot remove content url");
113 | }
114 |
115 | @Override
116 | public LocalFilesystemURL[] listChildren(LocalFilesystemURL inputURL) throws FileNotFoundException {
117 | throw new UnsupportedOperationException("readEntriesAtLocalURL() not supported for content:. Use resolveLocalFileSystemURL instead.");
118 | }
119 |
120 | @Override
121 | public JSONObject getFileMetadataForLocalURL(LocalFilesystemURL inputURL) throws FileNotFoundException {
122 | long size = -1;
123 | long lastModified = 0;
124 | Uri nativeUri = toNativeUri(inputURL);
125 | String mimeType = resourceApi.getMimeType(nativeUri);
126 | Cursor cursor = openCursorForURL(nativeUri);
127 | try {
128 | if (cursor != null && cursor.moveToFirst()) {
129 | Long sizeForCursor = resourceSizeForCursor(cursor);
130 | if (sizeForCursor != null) {
131 | size = sizeForCursor.longValue();
132 | }
133 | Long modified = lastModifiedDateForCursor(cursor);
134 | if (modified != null)
135 | lastModified = modified.longValue();
136 | } else {
137 | // Some content providers don't support cursors at all!
138 | CordovaResourceApi.OpenForReadResult offr = resourceApi.openForRead(nativeUri);
139 | size = offr.length;
140 | }
141 | } catch (IOException e) {
142 | FileNotFoundException fnfe = new FileNotFoundException();
143 | fnfe.initCause(e);
144 | throw fnfe;
145 | } finally {
146 | if (cursor != null)
147 | cursor.close();
148 | }
149 |
150 | JSONObject metadata = new JSONObject();
151 | try {
152 | metadata.put("size", size);
153 | metadata.put("type", mimeType);
154 | metadata.put("name", name);
155 | metadata.put("fullPath", inputURL.path);
156 | metadata.put("lastModifiedDate", lastModified);
157 | } catch (JSONException e) {
158 | return null;
159 | }
160 | return metadata;
161 | }
162 |
163 | @Override
164 | public long writeToFileAtURL(LocalFilesystemURL inputURL, String data,
165 | int offset, boolean isBinary) throws NoModificationAllowedException {
166 | throw new NoModificationAllowedException("Couldn't write to file given its content URI");
167 | }
168 | @Override
169 | public long truncateFileAtURL(LocalFilesystemURL inputURL, long size)
170 | throws NoModificationAllowedException {
171 | throw new NoModificationAllowedException("Couldn't truncate file given its content URI");
172 | }
173 |
174 | protected Cursor openCursorForURL(Uri nativeUri) {
175 | ContentResolver contentResolver = context.getContentResolver();
176 | try {
177 | return contentResolver.query(nativeUri, null, null, null, null);
178 | } catch (UnsupportedOperationException e) {
179 | return null;
180 | }
181 | }
182 |
183 | private Long resourceSizeForCursor(Cursor cursor) {
184 | int columnIndex = cursor.getColumnIndex(OpenableColumns.SIZE);
185 | if (columnIndex != -1) {
186 | String sizeStr = cursor.getString(columnIndex);
187 | if (sizeStr != null) {
188 | return Long.parseLong(sizeStr);
189 | }
190 | }
191 | return null;
192 | }
193 |
194 | protected Long lastModifiedDateForCursor(Cursor cursor) {
195 | int columnIndex = cursor.getColumnIndex(MediaStore.MediaColumns.DATE_MODIFIED);
196 | if (columnIndex == -1) {
197 | columnIndex = cursor.getColumnIndex(DocumentsContract.Document.COLUMN_LAST_MODIFIED);
198 | }
199 | if (columnIndex != -1) {
200 | String dateStr = cursor.getString(columnIndex);
201 | if (dateStr != null) {
202 | return Long.parseLong(dateStr);
203 | }
204 | }
205 | return null;
206 | }
207 |
208 | @Override
209 | public String filesystemPathForURL(LocalFilesystemURL url) {
210 | File f = resourceApi.mapUriToFile(toNativeUri(url));
211 | return f == null ? null : f.getAbsolutePath();
212 | }
213 |
214 | @Override
215 | public LocalFilesystemURL URLforFilesystemPath(String path) {
216 | // Returns null as we don't support reverse mapping back to content:// URLs
217 | return null;
218 | }
219 |
220 | @Override
221 | public boolean canRemoveFileAtLocalURL(LocalFilesystemURL inputURL) {
222 | return true;
223 | }
224 | }
225 |
--------------------------------------------------------------------------------
/src/android/DirectoryManager.java:
--------------------------------------------------------------------------------
1 | /*
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. See the NOTICE file
4 | distributed with this work for additional information
5 | regarding copyright ownership. The ASF licenses this file
6 | to you under the Apache License, Version 2.0 (the
7 | "License"); you may not use this file except in compliance
8 | with the License. You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing,
13 | software distributed under the License is distributed on an
14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | KIND, either express or implied. See the License for the
16 | specific language governing permissions and limitations
17 | under the License.
18 | */
19 | package org.apache.cordova.file;
20 |
21 | import android.os.Environment;
22 | import android.os.StatFs;
23 |
24 | import java.io.File;
25 |
26 | /**
27 | * This class provides file directory utilities.
28 | * All file operations are performed on the SD card.
29 | *
30 | * It is used by the FileUtils class.
31 | */
32 | public class DirectoryManager {
33 |
34 | @SuppressWarnings("unused")
35 | private static final String LOG_TAG = "DirectoryManager";
36 |
37 | /**
38 | * Determine if a file or directory exists.
39 | * @param name The name of the file to check.
40 | * @return T=exists, F=not found
41 | */
42 | public static boolean testFileExists(String name) {
43 | boolean status;
44 |
45 | // If SD card exists
46 | if ((testSaveLocationExists()) && (!name.equals(""))) {
47 | File path = Environment.getExternalStorageDirectory();
48 | File newPath = constructFilePaths(path.toString(), name);
49 | status = newPath.exists();
50 | }
51 | // If no SD card
52 | else {
53 | status = false;
54 | }
55 | return status;
56 | }
57 |
58 | /**
59 | * Get the free space in external storage
60 | *
61 | * @return Size in KB or -1 if not available
62 | */
63 | public static long getFreeExternalStorageSpace() {
64 | String status = Environment.getExternalStorageState();
65 | long freeSpaceInBytes = 0;
66 |
67 | // Check if external storage exists
68 | if (status.equals(Environment.MEDIA_MOUNTED)) {
69 | freeSpaceInBytes = getFreeSpaceInBytes(Environment.getExternalStorageDirectory().getPath());
70 | } else {
71 | // If no external storage then return -1
72 | return -1;
73 | }
74 |
75 | return freeSpaceInBytes / 1024;
76 | }
77 |
78 | /**
79 | * Given a path return the number of free bytes in the filesystem containing the path.
80 | *
81 | * @param path to the file system
82 | * @return free space in bytes
83 | */
84 | public static long getFreeSpaceInBytes(String path) {
85 | try {
86 | StatFs stat = new StatFs(path);
87 | long blockSize = stat.getBlockSize();
88 | long availableBlocks = stat.getAvailableBlocks();
89 | return availableBlocks * blockSize;
90 | } catch (IllegalArgumentException e) {
91 | // The path was invalid. Just return 0 free bytes.
92 | return 0;
93 | }
94 | }
95 |
96 | /**
97 | * Determine if SD card exists.
98 | *
99 | * @return T=exists, F=not found
100 | */
101 | public static boolean testSaveLocationExists() {
102 | String sDCardStatus = Environment.getExternalStorageState();
103 | boolean status;
104 |
105 | // If SD card is mounted
106 | if (sDCardStatus.equals(Environment.MEDIA_MOUNTED)) {
107 | status = true;
108 | }
109 |
110 | // If no SD card
111 | else {
112 | status = false;
113 | }
114 | return status;
115 | }
116 |
117 | /**
118 | * Create a new file object from two file paths.
119 | *
120 | * @param file1 Base file path
121 | * @param file2 Remaining file path
122 | * @return File object
123 | */
124 | private static File constructFilePaths (String file1, String file2) {
125 | File newPath;
126 | if (file2.startsWith(file1)) {
127 | newPath = new File(file2);
128 | }
129 | else {
130 | newPath = new File(file1 + "/" + file2);
131 | }
132 | return newPath;
133 | }
134 | }
135 |
--------------------------------------------------------------------------------
/src/android/EncodingException.java:
--------------------------------------------------------------------------------
1 | /*
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. See the NOTICE file
4 | distributed with this work for additional information
5 | regarding copyright ownership. The ASF licenses this file
6 | to you under the Apache License, Version 2.0 (the
7 | "License"); you may not use this file except in compliance
8 | with the License. You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing,
13 | software distributed under the License is distributed on an
14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | KIND, either express or implied. See the License for the
16 | specific language governing permissions and limitations
17 | under the License.
18 | */
19 |
20 | package org.apache.cordova.file;
21 |
22 | @SuppressWarnings("serial")
23 | public class EncodingException extends Exception {
24 |
25 | public EncodingException(String message) {
26 | super(message);
27 | }
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/src/android/FileExistsException.java:
--------------------------------------------------------------------------------
1 | /*
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. See the NOTICE file
4 | distributed with this work for additional information
5 | regarding copyright ownership. The ASF licenses this file
6 | to you under the Apache License, Version 2.0 (the
7 | "License"); you may not use this file except in compliance
8 | with the License. You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing,
13 | software distributed under the License is distributed on an
14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | KIND, either express or implied. See the License for the
16 | specific language governing permissions and limitations
17 | under the License.
18 | */
19 |
20 | package org.apache.cordova.file;
21 |
22 | @SuppressWarnings("serial")
23 | public class FileExistsException extends Exception {
24 |
25 | public FileExistsException(String msg) {
26 | super(msg);
27 | }
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/src/android/InvalidModificationException.java:
--------------------------------------------------------------------------------
1 | /*
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. See the NOTICE file
4 | distributed with this work for additional information
5 | regarding copyright ownership. The ASF licenses this file
6 | to you under the Apache License, Version 2.0 (the
7 | "License"); you may not use this file except in compliance
8 | with the License. You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing,
13 | software distributed under the License is distributed on an
14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | KIND, either express or implied. See the License for the
16 | specific language governing permissions and limitations
17 | under the License.
18 | */
19 |
20 |
21 | package org.apache.cordova.file;
22 |
23 | @SuppressWarnings("serial")
24 | public class InvalidModificationException extends Exception {
25 |
26 | public InvalidModificationException(String message) {
27 | super(message);
28 | }
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/src/android/LocalFilesystemURL.java:
--------------------------------------------------------------------------------
1 | /*
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. See the NOTICE file
4 | distributed with this work for additional information
5 | regarding copyright ownership. The ASF licenses this file
6 | to you under the Apache License, Version 2.0 (the
7 | "License"); you may not use this file except in compliance
8 | with the License. You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing,
13 | software distributed under the License is distributed on an
14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | KIND, either express or implied. See the License for the
16 | specific language governing permissions and limitations
17 | under the License.
18 | */
19 | package org.apache.cordova.file;
20 |
21 | import android.net.Uri;
22 |
23 | public class LocalFilesystemURL {
24 |
25 | public static final String FILESYSTEM_PROTOCOL = "cdvfile";
26 | public static final String CDVFILE_KEYWORD = "__cdvfile_";
27 |
28 | public final Uri uri;
29 | public final String fsName;
30 | public final String path;
31 | public final boolean isDirectory;
32 |
33 | private LocalFilesystemURL(Uri uri, String fsName, String fsPath, boolean isDirectory) {
34 | this.uri = uri;
35 | this.fsName = fsName;
36 | this.path = fsPath;
37 | this.isDirectory = isDirectory;
38 | }
39 |
40 | public static LocalFilesystemURL parse(Uri uri) {
41 | if(!uri.toString().contains(CDVFILE_KEYWORD)) {
42 | return null;
43 | }
44 |
45 | String path = uri.getPath();
46 | if (path.length() < 1) {
47 | return null;
48 | }
49 |
50 | int firstSlashIdx = path.indexOf('/', 1);
51 | if (firstSlashIdx < 0) {
52 | return null;
53 | }
54 |
55 | String fsName = path.substring(1, firstSlashIdx);
56 | fsName = fsName.substring(CDVFILE_KEYWORD.length());
57 | fsName = fsName.substring(0, fsName.length() - 2);
58 |
59 | path = path.substring(firstSlashIdx);
60 |
61 | boolean isDirectory = path.charAt(path.length() - 1) == '/';
62 | return new LocalFilesystemURL(uri, fsName, path, isDirectory);
63 | }
64 |
65 | public static LocalFilesystemURL parse(String uri) {
66 | return parse(Uri.parse(uri));
67 | }
68 |
69 | public static String fsNameToCdvKeyword(String fsName) { return CDVFILE_KEYWORD + fsName + "__"; }
70 |
71 | public String toString() {
72 | return uri.toString();
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/src/android/NoModificationAllowedException.java:
--------------------------------------------------------------------------------
1 | /*
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. See the NOTICE file
4 | distributed with this work for additional information
5 | regarding copyright ownership. The ASF licenses this file
6 | to you under the Apache License, Version 2.0 (the
7 | "License"); you may not use this file except in compliance
8 | with the License. You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing,
13 | software distributed under the License is distributed on an
14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | KIND, either express or implied. See the License for the
16 | specific language governing permissions and limitations
17 | under the License.
18 | */
19 |
20 | package org.apache.cordova.file;
21 |
22 | @SuppressWarnings("serial")
23 | public class NoModificationAllowedException extends Exception {
24 |
25 | public NoModificationAllowedException(String message) {
26 | super(message);
27 | }
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/src/android/PendingRequests.java:
--------------------------------------------------------------------------------
1 | /*
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. See the NOTICE file
4 | distributed with this work for additional information
5 | regarding copyright ownership. The ASF licenses this file
6 | to you under the Apache License, Version 2.0 (the
7 | "License"); you may not use this file except in compliance
8 | with the License. You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing,
13 | software distributed under the License is distributed on an
14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | KIND, either express or implied. See the License for the
16 | specific language governing permissions and limitations
17 | under the License.
18 | */
19 | package org.apache.cordova.file;
20 |
21 | import android.util.SparseArray;
22 |
23 | import org.apache.cordova.CallbackContext;
24 |
25 | /**
26 | * Holds pending runtime permission requests
27 | */
28 | class PendingRequests {
29 | private int currentReqId = 0;
30 | private SparseArray requests = new SparseArray();
31 |
32 | /**
33 | * Creates a request and adds it to the array of pending requests. Each created request gets a
34 | * unique result code for use with requestPermission()
35 | * @param rawArgs The raw arguments passed to the plugin
36 | * @param action The action this request corresponds to (get file, etc.)
37 | * @param callbackContext The CallbackContext for this plugin call
38 | * @return The request code that can be used to retrieve the Request object
39 | */
40 | public synchronized int createRequest(String rawArgs, int action, CallbackContext callbackContext) {
41 | Request req = new Request(rawArgs, action, callbackContext);
42 | requests.put(req.requestCode, req);
43 | return req.requestCode;
44 | }
45 |
46 | /**
47 | * Gets the request corresponding to this request code and removes it from the pending requests
48 | * @param requestCode The request code for the desired request
49 | * @return The request corresponding to the given request code or null if such a
50 | * request is not found
51 | */
52 | public synchronized Request getAndRemove(int requestCode) {
53 | Request result = requests.get(requestCode);
54 | requests.remove(requestCode);
55 | return result;
56 | }
57 |
58 | /**
59 | * Holds the options and CallbackContext for a call made to the plugin.
60 | */
61 | public class Request {
62 |
63 | // Unique int used to identify this request in any Android permission callback
64 | private int requestCode;
65 |
66 | // Action to be performed after permission request result
67 | private int action;
68 |
69 | // Raw arguments passed to plugin
70 | private String rawArgs;
71 |
72 | // The callback context for this plugin request
73 | private CallbackContext callbackContext;
74 |
75 | private Request(String rawArgs, int action, CallbackContext callbackContext) {
76 | this.rawArgs = rawArgs;
77 | this.action = action;
78 | this.callbackContext = callbackContext;
79 | this.requestCode = currentReqId ++;
80 | }
81 |
82 | public int getAction() {
83 | return this.action;
84 | }
85 |
86 | public String getRawArgs() {
87 | return rawArgs;
88 | }
89 |
90 | public CallbackContext getCallbackContext() {
91 | return callbackContext;
92 | }
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/src/android/TypeMismatchException.java:
--------------------------------------------------------------------------------
1 | /*
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. See the NOTICE file
4 | distributed with this work for additional information
5 | regarding copyright ownership. The ASF licenses this file
6 | to you under the Apache License, Version 2.0 (the
7 | "License"); you may not use this file except in compliance
8 | with the License. You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing,
13 | software distributed under the License is distributed on an
14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | KIND, either express or implied. See the License for the
16 | specific language governing permissions and limitations
17 | under the License.
18 | */
19 |
20 |
21 | package org.apache.cordova.file;
22 |
23 | @SuppressWarnings("serial")
24 | public class TypeMismatchException extends Exception {
25 |
26 | public TypeMismatchException(String message) {
27 | super(message);
28 | }
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/src/android/build-extras.gradle:
--------------------------------------------------------------------------------
1 | /*
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. See the NOTICE file
4 | distributed with this work for additional information
5 | regarding copyright ownership. The ASF licenses this file
6 | to you under the Apache License, Version 2.0 (the
7 | "License"); you may not use this file except in compliance
8 | with the License. You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing,
13 | software distributed under the License is distributed on an
14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | KIND, either express or implied. See the License for the
16 | specific language governing permissions and limitations
17 | under the License.
18 | */
19 | ext.postBuildExtras = {
20 | def inAssetsDir = file("assets")
21 | def outAssetsDir = inAssetsDir
22 | def outFile = new File(outAssetsDir, "cdvasset.manifest")
23 |
24 | def newTask = task("cdvCreateAssetManifest") << {
25 | def contents = new HashMap()
26 | def sizes = new HashMap()
27 | contents[""] = inAssetsDir.list()
28 | def tree = fileTree(dir: inAssetsDir)
29 | tree.visit { fileDetails ->
30 | if (fileDetails.isDirectory()) {
31 | contents[fileDetails.relativePath.toString()] = fileDetails.file.list()
32 | } else {
33 | sizes[fileDetails.relativePath.toString()] = fileDetails.file.length()
34 | }
35 | }
36 |
37 | outAssetsDir.mkdirs()
38 | outFile.withObjectOutputStream { oos ->
39 | oos.writeObject(contents)
40 | oos.writeObject(sizes)
41 | }
42 | }
43 | newTask.inputs.dir inAssetsDir
44 | newTask.outputs.file outFile
45 | def preBuildTask = tasks["preBuild"]
46 | preBuildTask.dependsOn(newTask)
47 | }
48 |
--------------------------------------------------------------------------------
/src/ios/CDVAssetLibraryFilesystem.h:
--------------------------------------------------------------------------------
1 | /*
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. See the NOTICE file
4 | distributed with this work for additional information
5 | regarding copyright ownership. The ASF licenses this file
6 | to you under the Apache License, Version 2.0 (the
7 | "License"); you may not use this file except in compliance
8 | with the License. You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing,
13 | software distributed under the License is distributed on an
14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | KIND, either express or implied. See the License for the
16 | specific language governing permissions and limitations
17 | under the License.
18 | */
19 |
20 | #import "CDVFile.h"
21 |
22 | extern NSString* const kCDVAssetsLibraryPrefix;
23 | extern NSString* const kCDVAssetsLibraryScheme;
24 |
25 | @interface CDVAssetLibraryFilesystem : NSObject {
26 | }
27 |
28 | - (id) initWithName:(NSString *)name;
29 |
30 | @end
31 |
--------------------------------------------------------------------------------
/src/ios/CDVAssetLibraryFilesystem.m:
--------------------------------------------------------------------------------
1 | /*
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. See the NOTICE file
4 | distributed with this work for additional information
5 | regarding copyright ownership. The ASF licenses this file
6 | to you under the Apache License, Version 2.0 (the
7 | "License"); you may not use this file except in compliance
8 | with the License. You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing,
13 | software distributed under the License is distributed on an
14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | KIND, either express or implied. See the License for the
16 | specific language governing permissions and limitations
17 | under the License.
18 | */
19 |
20 | #import "CDVFile.h"
21 | #import "CDVAssetLibraryFilesystem.h"
22 | #import
23 | #import
24 | #import
25 | #import
26 | #import
27 |
28 | NSString* const kCDVAssetsLibraryPrefix = @"assets-library://";
29 | NSString* const kCDVAssetsLibraryScheme = @"assets-library";
30 |
31 | @implementation CDVAssetLibraryFilesystem
32 | @synthesize name=_name, urlTransformer;
33 |
34 |
35 | /*
36 | The CDVAssetLibraryFilesystem works with resources which are identified
37 | by iOS as
38 | asset-library://
39 | and represents them internally as URLs of the form
40 | cdvfile://localhost/assets-library/
41 | */
42 |
43 | - (NSURL *)assetLibraryURLForLocalURL:(CDVFilesystemURL *)url
44 | {
45 | if ([url.url.scheme isEqualToString:kCDVFilesystemURLPrefix]) {
46 | NSString *path = [[url.url absoluteString] substringFromIndex:[@"cdvfile://localhost/assets-library" length]];
47 | return [NSURL URLWithString:[NSString stringWithFormat:@"assets-library:/%@", path]];
48 | }
49 | return url.url;
50 | }
51 |
52 | - (CDVPluginResult *)entryForLocalURI:(CDVFilesystemURL *)url
53 | {
54 | NSDictionary* entry = [self makeEntryForLocalURL:url];
55 | return [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:entry];
56 | }
57 |
58 | - (NSDictionary *)makeEntryForLocalURL:(CDVFilesystemURL *)url {
59 | return [self makeEntryForPath:url.fullPath isDirectory:NO];
60 | }
61 |
62 | - (NSDictionary*)makeEntryForPath:(NSString*)fullPath isDirectory:(BOOL)isDir
63 | {
64 | NSMutableDictionary* dirEntry = [NSMutableDictionary dictionaryWithCapacity:5];
65 | NSString* lastPart = [fullPath lastPathComponent];
66 | if (isDir && ![fullPath hasSuffix:@"/"]) {
67 | fullPath = [fullPath stringByAppendingString:@"/"];
68 | }
69 | [dirEntry setObject:[NSNumber numberWithBool:!isDir] forKey:@"isFile"];
70 | [dirEntry setObject:[NSNumber numberWithBool:isDir] forKey:@"isDirectory"];
71 | [dirEntry setObject:fullPath forKey:@"fullPath"];
72 | [dirEntry setObject:lastPart forKey:@"name"];
73 | [dirEntry setObject:self.name forKey: @"filesystemName"];
74 |
75 | NSURL* nativeURL = [NSURL URLWithString:[NSString stringWithFormat:@"assets-library:/%@",fullPath]];
76 | if (self.urlTransformer) {
77 | nativeURL = self.urlTransformer(nativeURL);
78 | }
79 | dirEntry[@"nativeURL"] = [nativeURL absoluteString];
80 |
81 | return dirEntry;
82 | }
83 |
84 | /* helper function to get the mimeType from the file extension
85 | * IN:
86 | * NSString* fullPath - filename (may include path)
87 | * OUT:
88 | * NSString* the mime type as type/subtype. nil if not able to determine
89 | */
90 | + (NSString*)getMimeTypeFromPath:(NSString*)fullPath
91 | {
92 | NSString* mimeType = nil;
93 |
94 | if (fullPath) {
95 | CFStringRef typeId = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (__bridge CFStringRef)[fullPath pathExtension], NULL);
96 | if (typeId) {
97 | mimeType = (__bridge_transfer NSString*)UTTypeCopyPreferredTagWithClass(typeId, kUTTagClassMIMEType);
98 | if (!mimeType) {
99 | // special case for m4a
100 | if ([(__bridge NSString*)typeId rangeOfString : @"m4a-audio"].location != NSNotFound) {
101 | mimeType = @"audio/mp4";
102 | } else if ([[fullPath pathExtension] rangeOfString:@"wav"].location != NSNotFound) {
103 | mimeType = @"audio/wav";
104 | } else if ([[fullPath pathExtension] rangeOfString:@"css"].location != NSNotFound) {
105 | mimeType = @"text/css";
106 | }
107 | }
108 | CFRelease(typeId);
109 | }
110 | }
111 | return mimeType;
112 | }
113 |
114 | - (id)initWithName:(NSString *)name
115 | {
116 | if (self) {
117 | self.name = name;
118 | }
119 | return self;
120 | }
121 |
122 | - (CDVPluginResult *)getFileForURL:(CDVFilesystemURL *)baseURI requestedPath:(NSString *)requestedPath options:(NSDictionary *)options
123 | {
124 | // return unsupported result for assets-library URLs
125 | return [CDVPluginResult resultWithStatus:CDVCommandStatus_MALFORMED_URL_EXCEPTION messageAsString:@"getFile not supported for assets-library URLs."];
126 | }
127 |
128 | - (CDVPluginResult*)getParentForURL:(CDVFilesystemURL *)localURI
129 | {
130 | // we don't (yet?) support getting the parent of an asset
131 | return [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:NOT_READABLE_ERR];
132 | }
133 |
134 | - (CDVPluginResult*)setMetadataForURL:(CDVFilesystemURL *)localURI withObject:(NSDictionary *)options
135 | {
136 | // setMetadata doesn't make sense for asset library files
137 | return [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR];
138 | }
139 |
140 | - (CDVPluginResult *)removeFileAtURL:(CDVFilesystemURL *)localURI
141 | {
142 | // return error for assets-library URLs
143 | return [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:INVALID_MODIFICATION_ERR];
144 | }
145 |
146 | - (CDVPluginResult *)recursiveRemoveFileAtURL:(CDVFilesystemURL *)localURI
147 | {
148 | // return error for assets-library URLs
149 | return [CDVPluginResult resultWithStatus:CDVCommandStatus_MALFORMED_URL_EXCEPTION messageAsString:@"removeRecursively not supported for assets-library URLs."];
150 | }
151 |
152 | - (CDVPluginResult *)readEntriesAtURL:(CDVFilesystemURL *)localURI
153 | {
154 | // return unsupported result for assets-library URLs
155 | return [CDVPluginResult resultWithStatus:CDVCommandStatus_MALFORMED_URL_EXCEPTION messageAsString:@"readEntries not supported for assets-library URLs."];
156 | }
157 |
158 | - (CDVPluginResult *)truncateFileAtURL:(CDVFilesystemURL *)localURI atPosition:(unsigned long long)pos
159 | {
160 | // assets-library files can't be truncated
161 | return [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:NO_MODIFICATION_ALLOWED_ERR];
162 | }
163 |
164 | - (CDVPluginResult *)writeToFileAtURL:(CDVFilesystemURL *)localURL withData:(NSData*)encData append:(BOOL)shouldAppend
165 | {
166 | // text can't be written into assets-library files
167 | return [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:NO_MODIFICATION_ALLOWED_ERR];
168 | }
169 |
170 | - (void)copyFileToURL:(CDVFilesystemURL *)destURL withName:(NSString *)newName fromFileSystem:(NSObject *)srcFs atURL:(CDVFilesystemURL *)srcURL copy:(BOOL)bCopy callback:(void (^)(CDVPluginResult *))callback
171 | {
172 | // Copying to an assets library file is not doable, since we can't write it.
173 | CDVPluginResult *result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:INVALID_MODIFICATION_ERR];
174 | callback(result);
175 | }
176 |
177 | - (NSString *)filesystemPathForURL:(CDVFilesystemURL *)url
178 | {
179 | NSString *path = nil;
180 | if ([[url.url scheme] isEqualToString:kCDVAssetsLibraryScheme]) {
181 | path = [url.url path];
182 | } else {
183 | path = url.fullPath;
184 | }
185 | if ([path hasSuffix:@"/"]) {
186 | path = [path substringToIndex:([path length]-1)];
187 | }
188 | return path;
189 | }
190 |
191 | - (void)readFileAtURL:(CDVFilesystemURL *)localURL start:(NSInteger)start end:(NSInteger)end callback:(void (^)(NSData*, NSString* mimeType, CDVFileError))callback
192 | {
193 | ALAssetsLibraryAssetForURLResultBlock resultBlock = ^(ALAsset* asset) {
194 | if (asset) {
195 | // We have the asset! Get the data and send it off.
196 | ALAssetRepresentation* assetRepresentation = [asset defaultRepresentation];
197 | NSUInteger size = (end > start) ? (end - start) : [assetRepresentation size];
198 | Byte* buffer = (Byte*)malloc(size);
199 | NSUInteger bufferSize = [assetRepresentation getBytes:buffer fromOffset:start length:size error:nil];
200 | NSData* data = [NSData dataWithBytesNoCopy:buffer length:bufferSize freeWhenDone:YES];
201 | NSString* MIMEType = (__bridge_transfer NSString*)UTTypeCopyPreferredTagWithClass((__bridge CFStringRef)[assetRepresentation UTI], kUTTagClassMIMEType);
202 |
203 | callback(data, MIMEType, NO_ERROR);
204 | } else {
205 | callback(nil, nil, NOT_FOUND_ERR);
206 | }
207 | };
208 |
209 | ALAssetsLibraryAccessFailureBlock failureBlock = ^(NSError* error) {
210 | // Retrieving the asset failed for some reason. Send the appropriate error.
211 | NSLog(@"Error: %@", error);
212 | callback(nil, nil, SECURITY_ERR);
213 | };
214 |
215 | ALAssetsLibrary* assetsLibrary = [[ALAssetsLibrary alloc] init];
216 | [assetsLibrary assetForURL:[self assetLibraryURLForLocalURL:localURL] resultBlock:resultBlock failureBlock:failureBlock];
217 | }
218 |
219 | - (void)getFileMetadataForURL:(CDVFilesystemURL *)localURL callback:(void (^)(CDVPluginResult *))callback
220 | {
221 | // In this case, we need to use an asynchronous method to retrieve the file.
222 | // Because of this, we can't just assign to `result` and send it at the end of the method.
223 | // Instead, we return after calling the asynchronous method and send `result` in each of the blocks.
224 | ALAssetsLibraryAssetForURLResultBlock resultBlock = ^(ALAsset* asset) {
225 | if (asset) {
226 | // We have the asset! Populate the dictionary and send it off.
227 | NSMutableDictionary* fileInfo = [NSMutableDictionary dictionaryWithCapacity:5];
228 | ALAssetRepresentation* assetRepresentation = [asset defaultRepresentation];
229 | [fileInfo setObject:[NSNumber numberWithUnsignedLongLong:[assetRepresentation size]] forKey:@"size"];
230 | [fileInfo setObject:localURL.fullPath forKey:@"fullPath"];
231 | NSString* filename = [assetRepresentation filename];
232 | [fileInfo setObject:filename forKey:@"name"];
233 | [fileInfo setObject:[CDVAssetLibraryFilesystem getMimeTypeFromPath:filename] forKey:@"type"];
234 | NSDate* creationDate = [asset valueForProperty:ALAssetPropertyDate];
235 | NSNumber* msDate = [NSNumber numberWithDouble:[creationDate timeIntervalSince1970] * 1000];
236 | [fileInfo setObject:msDate forKey:@"lastModifiedDate"];
237 |
238 | callback([CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:fileInfo]);
239 | } else {
240 | // We couldn't find the asset. Send the appropriate error.
241 | callback([CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:NOT_FOUND_ERR]);
242 | }
243 | };
244 | ALAssetsLibraryAccessFailureBlock failureBlock = ^(NSError* error) {
245 | // Retrieving the asset failed for some reason. Send the appropriate error.
246 | callback([CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsString:[error localizedDescription]]);
247 | };
248 |
249 | ALAssetsLibrary* assetsLibrary = [[ALAssetsLibrary alloc] init];
250 | [assetsLibrary assetForURL:[self assetLibraryURLForLocalURL:localURL] resultBlock:resultBlock failureBlock:failureBlock];
251 | return;
252 | }
253 | @end
254 |
--------------------------------------------------------------------------------
/src/ios/CDVFile.bundle/PrivacyInfo.xcprivacy:
--------------------------------------------------------------------------------
1 |
2 |
20 |
21 |
22 |
23 | NSPrivacyTracking
24 |
25 | NSPrivacyTrackingDomains
26 |
27 | NSPrivacyAccessedAPITypes
28 |
29 |
30 | NSPrivacyAccessedAPIType
31 | NSPrivacyAccessedAPICategoryDiskSpace
32 | NSPrivacyAccessedAPITypeReasons
33 |
34 | E174.1
35 |
36 |
37 |
38 | NSPrivacyAccessedAPIType
39 | NSPrivacyAccessedAPICategoryFileTimestamp
40 | NSPrivacyAccessedAPITypeReasons
41 |
42 | C617.1
43 |
44 |
45 |
46 | NSPrivacyCollectedDataTypes
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/src/ios/CDVFile.h:
--------------------------------------------------------------------------------
1 | /*
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. See the NOTICE file
4 | distributed with this work for additional information
5 | regarding copyright ownership. The ASF licenses this file
6 | to you under the Apache License, Version 2.0 (the
7 | "License"); you may not use this file except in compliance
8 | with the License. You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing,
13 | software distributed under the License is distributed on an
14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | KIND, either express or implied. See the License for the
16 | specific language governing permissions and limitations
17 | under the License.
18 | */
19 |
20 | #import
21 | #import
22 |
23 | extern NSString* const kCDVAssetsLibraryPrefix;
24 | extern NSString* const kCDVFilesystemURLPrefix;
25 |
26 | enum CDVFileError {
27 | NO_ERROR = 0,
28 | NOT_FOUND_ERR = 1,
29 | SECURITY_ERR = 2,
30 | ABORT_ERR = 3,
31 | NOT_READABLE_ERR = 4,
32 | ENCODING_ERR = 5,
33 | NO_MODIFICATION_ALLOWED_ERR = 6,
34 | INVALID_STATE_ERR = 7,
35 | SYNTAX_ERR = 8,
36 | INVALID_MODIFICATION_ERR = 9,
37 | QUOTA_EXCEEDED_ERR = 10,
38 | TYPE_MISMATCH_ERR = 11,
39 | PATH_EXISTS_ERR = 12
40 | };
41 | typedef int CDVFileError;
42 |
43 | @interface CDVFilesystemURL : NSObject {
44 | NSURL *_url;
45 | NSString *_fileSystemName;
46 | NSString *_fullPath;
47 | }
48 |
49 | - (id) initWithString:(NSString*)strURL;
50 | - (id) initWithURL:(NSURL*)URL;
51 | + (CDVFilesystemURL *)fileSystemURLWithString:(NSString *)strURL;
52 | + (CDVFilesystemURL *)fileSystemURLWithURL:(NSURL *)URL;
53 |
54 | - (NSString *)absoluteURL;
55 |
56 | @property (atomic) NSURL *url;
57 | @property (atomic) NSString *fileSystemName;
58 | @property (atomic) NSString *fullPath;
59 |
60 | @end
61 |
62 | @interface CDVFilesystemURLProtocol : NSURLProtocol
63 | @end
64 |
65 | @protocol CDVFileSystem
66 | - (CDVPluginResult *)entryForLocalURI:(CDVFilesystemURL *)url;
67 | - (CDVPluginResult *)getFileForURL:(CDVFilesystemURL *)baseURI requestedPath:(NSString *)requestedPath options:(NSDictionary *)options;
68 | - (CDVPluginResult *)getParentForURL:(CDVFilesystemURL *)localURI;
69 | - (CDVPluginResult *)setMetadataForURL:(CDVFilesystemURL *)localURI withObject:(NSDictionary *)options;
70 | - (CDVPluginResult *)removeFileAtURL:(CDVFilesystemURL *)localURI;
71 | - (CDVPluginResult *)recursiveRemoveFileAtURL:(CDVFilesystemURL *)localURI;
72 | - (CDVPluginResult *)readEntriesAtURL:(CDVFilesystemURL *)localURI;
73 | - (CDVPluginResult *)truncateFileAtURL:(CDVFilesystemURL *)localURI atPosition:(unsigned long long)pos;
74 | - (CDVPluginResult *)writeToFileAtURL:(CDVFilesystemURL *)localURL withData:(NSData*)encData append:(BOOL)shouldAppend;
75 | - (void)copyFileToURL:(CDVFilesystemURL *)destURL withName:(NSString *)newName fromFileSystem:(NSObject *)srcFs atURL:(CDVFilesystemURL *)srcURL copy:(BOOL)bCopy callback:(void (^)(CDVPluginResult *))callback;
76 | - (void)readFileAtURL:(CDVFilesystemURL *)localURL start:(NSInteger)start end:(NSInteger)end callback:(void (^)(NSData*, NSString* mimeType, CDVFileError))callback;
77 | - (void)getFileMetadataForURL:(CDVFilesystemURL *)localURL callback:(void (^)(CDVPluginResult *))callback;
78 |
79 | - (NSDictionary *)makeEntryForLocalURL:(CDVFilesystemURL *)url;
80 | - (NSDictionary*)makeEntryForPath:(NSString*)fullPath isDirectory:(BOOL)isDir;
81 |
82 | @property (nonatomic,strong) NSString *name;
83 | @property (nonatomic, copy) NSURL*(^urlTransformer)(NSURL*);
84 |
85 | @optional
86 | - (NSString *)filesystemPathForURL:(CDVFilesystemURL *)localURI;
87 | - (CDVFilesystemURL *)URLforFilesystemPath:(NSString *)path;
88 |
89 | @end
90 |
91 | @interface CDVFile : CDVPlugin {
92 | NSString* rootDocsPath;
93 | NSString* appDocsPath;
94 | NSString* appLibraryPath;
95 | NSString* appTempPath;
96 |
97 | NSMutableArray* fileSystems_;
98 | BOOL userHasAllowed;
99 | }
100 |
101 | - (NSNumber*)checkFreeDiskSpace:(NSString*)appPath;
102 | - (NSDictionary*)makeEntryForPath:(NSString*)fullPath fileSystemName:(NSString *)fsName isDirectory:(BOOL)isDir;
103 | - (NSDictionary *)makeEntryForURL:(NSURL *)URL;
104 | - (CDVFilesystemURL *)fileSystemURLforLocalPath:(NSString *)localPath;
105 |
106 | - (NSObject *)filesystemForURL:(CDVFilesystemURL *)localURL;
107 |
108 | /* Native Registration API */
109 | - (void)registerFilesystem:(NSObject *)fs;
110 | - (NSObject *)fileSystemByName:(NSString *)fsName;
111 |
112 | /* Exec API */
113 | - (void)requestFileSystem:(CDVInvokedUrlCommand*)command;
114 | - (void)resolveLocalFileSystemURI:(CDVInvokedUrlCommand*)command;
115 | - (void)getDirectory:(CDVInvokedUrlCommand*)command;
116 | - (void)getFile:(CDVInvokedUrlCommand*)command;
117 | - (void)getParent:(CDVInvokedUrlCommand*)command;
118 | - (void)removeRecursively:(CDVInvokedUrlCommand*)command;
119 | - (void)remove:(CDVInvokedUrlCommand*)command;
120 | - (void)copyTo:(CDVInvokedUrlCommand*)command;
121 | - (void)moveTo:(CDVInvokedUrlCommand*)command;
122 | - (void)getFileMetadata:(CDVInvokedUrlCommand*)command;
123 | - (void)readEntries:(CDVInvokedUrlCommand*)command;
124 | - (void)readAsText:(CDVInvokedUrlCommand*)command;
125 | - (void)readAsDataURL:(CDVInvokedUrlCommand*)command;
126 | - (void)readAsArrayBuffer:(CDVInvokedUrlCommand*)command;
127 | - (void)write:(CDVInvokedUrlCommand*)command;
128 | - (void)testFileExists:(CDVInvokedUrlCommand*)command;
129 | - (void)testDirectoryExists:(CDVInvokedUrlCommand*)command;
130 | - (void)getFreeDiskSpace:(CDVInvokedUrlCommand*)command;
131 | - (void)truncate:(CDVInvokedUrlCommand*)command;
132 | - (void)doCopyMove:(CDVInvokedUrlCommand*)command isCopy:(BOOL)bCopy;
133 |
134 | /* Compatibilty with older File API */
135 | - (NSString*)getMimeTypeFromPath:(NSString*)fullPath;
136 | - (NSDictionary *)getDirectoryEntry:(NSString *)target isDirectory:(BOOL)bDirRequest;
137 |
138 | /* Conversion between filesystem paths and URLs */
139 | - (NSString *)filesystemPathForURL:(CDVFilesystemURL *)URL;
140 |
141 | /* Internal methods for testing */
142 | - (void)_getLocalFilesystemPath:(CDVInvokedUrlCommand*)command;
143 |
144 | @property (nonatomic, strong) NSString* rootDocsPath;
145 | @property (nonatomic, strong) NSString* appDocsPath;
146 | @property (nonatomic, strong) NSString* appLibraryPath;
147 | @property (nonatomic, strong) NSString* appTempPath;
148 | @property (nonatomic, strong) NSString* persistentPath;
149 | @property (nonatomic, strong) NSString* temporaryPath;
150 | @property (nonatomic, strong) NSMutableArray* fileSystems;
151 |
152 | @property BOOL userHasAllowed;
153 |
154 | @end
155 |
156 | #define kW3FileTemporary @"temporary"
157 | #define kW3FilePersistent @"persistent"
158 |
--------------------------------------------------------------------------------
/src/ios/CDVLocalFilesystem.h:
--------------------------------------------------------------------------------
1 | /*
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. See the NOTICE file
4 | distributed with this work for additional information
5 | regarding copyright ownership. The ASF licenses this file
6 | to you under the Apache License, Version 2.0 (the
7 | "License"); you may not use this file except in compliance
8 | with the License. You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing,
13 | software distributed under the License is distributed on an
14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | KIND, either express or implied. See the License for the
16 | specific language governing permissions and limitations
17 | under the License.
18 | */
19 |
20 | #import "CDVFile.h"
21 |
22 | @interface CDVLocalFilesystem : NSObject {
23 | NSString *_name;
24 | NSString *_fsRoot;
25 | }
26 |
27 | - (id) initWithName:(NSString *)name root:(NSString *)fsRoot;
28 | + (NSString*)getMimeTypeFromPath:(NSString*)fullPath;
29 |
30 | @property (nonatomic,strong) NSString *fsRoot;
31 |
32 | @end
33 |
--------------------------------------------------------------------------------
/src/osx/CDVFile.h:
--------------------------------------------------------------------------------
1 | /*
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. See the NOTICE file
4 | distributed with this work for additional information
5 | regarding copyright ownership. The ASF licenses this file
6 | to you under the Apache License, Version 2.0 (the
7 | "License"); you may not use this file except in compliance
8 | with the License. You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing,
13 | software distributed under the License is distributed on an
14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | KIND, either express or implied. See the License for the
16 | specific language governing permissions and limitations
17 | under the License.
18 | */
19 |
20 | #import
21 | #import
22 |
23 | NSString* const kCDVFilesystemURLPrefix;
24 |
25 | /**
26 | * The default filesystems if non are specified.
27 | */
28 | #define CDV_FILESYSTEMS_DEFAULT @"documents,cache,bundle,root"
29 |
30 | /**
31 | * Preference name of the extra filesystems to be "mounted". the following are supported:
32 | * 'bundle' - mounts the application directory
33 | * 'documents' - mounts the users Documents directory (~/Documents)
34 | * 'root' - mounts the root file system
35 | * 'cache' - mounts the caches directory (~/Library/Caches/ *)srcFs atURL:(CDVFilesystemURL *)srcURL copy:(BOOL)bCopy callback:(void (^)(CDVPluginResult *))callback;
89 | - (void)readFileAtURL:(CDVFilesystemURL *)localURL start:(NSInteger)start end:(NSInteger)end callback:(void (^)(NSData*, NSString* mimeType, CDVFileError))callback;
90 | - (void)getFileMetadataForURL:(CDVFilesystemURL *)localURL callback:(void (^)(CDVPluginResult *))callback;
91 |
92 | - (NSDictionary *)makeEntryForLocalURL:(CDVFilesystemURL *)url;
93 | - (NSDictionary*)makeEntryForPath:(NSString*)fullPath isDirectory:(BOOL)isDir;
94 |
95 | @property (nonatomic,strong) NSString *name;
96 | @property (nonatomic, copy) NSURL*(^urlTransformer)(NSURL*);
97 |
98 | @optional
99 | - (NSString *)filesystemPathForURL:(CDVFilesystemURL *)localURI;
100 | - (CDVFilesystemURL *)URLforFilesystemPath:(NSString *)path;
101 |
102 | @end
103 |
104 | @interface CDVFile : CDVPlugin {
105 | NSString* rootDocsPath;
106 | NSString* appDocsPath;
107 | NSString* appLibraryPath;
108 | NSString* appTempPath;
109 |
110 | NSMutableArray* fileSystems_;
111 | BOOL userHasAllowed;
112 | }
113 |
114 | - (NSNumber*)checkFreeDiskSpace:(NSString*)appPath;
115 | - (NSDictionary*)makeEntryForPath:(NSString*)fullPath fileSystemName:(NSString *)fsName isDirectory:(BOOL)isDir;
116 | - (NSDictionary *)makeEntryForURL:(NSURL *)URL;
117 | - (CDVFilesystemURL *)fileSystemURLforLocalPath:(NSString *)localPath;
118 |
119 | - (NSObject *)filesystemForURL:(CDVFilesystemURL *)localURL;
120 |
121 | /* Native Registration API */
122 | - (void)registerFilesystem:(NSObject *)fs;
123 | - (NSObject *)fileSystemByName:(NSString *)fsName;
124 |
125 | /* Exec API */
126 | - (void)requestFileSystem:(CDVInvokedUrlCommand*)command;
127 | - (void)resolveLocalFileSystemURI:(CDVInvokedUrlCommand*)command;
128 | - (void)getDirectory:(CDVInvokedUrlCommand*)command;
129 | - (void)getFile:(CDVInvokedUrlCommand*)command;
130 | - (void)getParent:(CDVInvokedUrlCommand*)command;
131 | - (void)removeRecursively:(CDVInvokedUrlCommand*)command;
132 | - (void)remove:(CDVInvokedUrlCommand*)command;
133 | - (void)copyTo:(CDVInvokedUrlCommand*)command;
134 | - (void)moveTo:(CDVInvokedUrlCommand*)command;
135 | - (void)getFileMetadata:(CDVInvokedUrlCommand*)command;
136 | - (void)readEntries:(CDVInvokedUrlCommand*)command;
137 | - (void)readAsText:(CDVInvokedUrlCommand*)command;
138 | - (void)readAsDataURL:(CDVInvokedUrlCommand*)command;
139 | - (void)readAsArrayBuffer:(CDVInvokedUrlCommand*)command;
140 | - (void)write:(CDVInvokedUrlCommand*)command;
141 | - (void)testFileExists:(CDVInvokedUrlCommand*)command;
142 | - (void)testDirectoryExists:(CDVInvokedUrlCommand*)command;
143 | - (void)getFreeDiskSpace:(CDVInvokedUrlCommand*)command;
144 | - (void)truncate:(CDVInvokedUrlCommand*)command;
145 | - (void)doCopyMove:(CDVInvokedUrlCommand*)command isCopy:(BOOL)bCopy;
146 |
147 | /* Compatibilty with older File API */
148 | - (NSString*)getMimeTypeFromPath:(NSString*)fullPath;
149 | - (NSDictionary *)getDirectoryEntry:(NSString *)target isDirectory:(BOOL)bDirRequest;
150 |
151 | /* Conversion between filesystem paths and URLs */
152 | - (NSString *)filesystemPathForURL:(CDVFilesystemURL *)URL;
153 |
154 | /* Internal methods for testing */
155 | - (void)_getLocalFilesystemPath:(CDVInvokedUrlCommand*)command;
156 |
157 | /**
158 | * local path of the 'documents' file system (~/Documents)
159 | */
160 | @property (nonatomic, strong) NSString* appDocsPath;
161 |
162 | /**
163 | * local path of the 'applicationStorageDirectory' file system (~/Library/Application Support/)
164 | */
165 | @property (nonatomic, strong) NSString* appSupportPath;
166 |
167 | /**
168 | * local path of the 'persistent' file system (~/Library/Application Support//files)
169 | */
170 | @property (nonatomic, strong) NSString* appDataPath;
171 |
172 | /**
173 | * local path of the 'documents' file system (~/Documents)
174 | */
175 | @property (nonatomic, strong) NSString* appTempPath;
176 |
177 | /**
178 | * local path of the 'cache' file system (~/Library/Caches/)
179 | */
180 | @property (nonatomic, strong) NSString* appCachePath;
181 |
182 | /**
183 | * registered file systems
184 | */
185 | @property (nonatomic, strong) NSMutableArray* fileSystems;
186 |
187 | @property BOOL userHasAllowed;
188 |
189 | @end
190 |
--------------------------------------------------------------------------------
/src/osx/CDVLocalFilesystem.h:
--------------------------------------------------------------------------------
1 | /*
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. See the NOTICE file
4 | distributed with this work for additional information
5 | regarding copyright ownership. The ASF licenses this file
6 | to you under the Apache License, Version 2.0 (the
7 | "License"); you may not use this file except in compliance
8 | with the License. You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing,
13 | software distributed under the License is distributed on an
14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | KIND, either express or implied. See the License for the
16 | specific language governing permissions and limitations
17 | under the License.
18 | */
19 |
20 | #import "CDVFile.h"
21 |
22 | @interface CDVLocalFilesystem : NSObject {
23 | NSString *_name;
24 | NSString *_fsRoot;
25 | }
26 |
27 | - (id) initWithName:(NSString *)name root:(NSString *)fsRoot;
28 | + (NSString*)getMimeTypeFromPath:(NSString*)fullPath;
29 |
30 | @property (nonatomic,strong) NSString *fsRoot;
31 |
32 | @end
33 |
--------------------------------------------------------------------------------
/tests/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cordova-plugin-file-tests",
3 | "version": "8.1.4-dev",
4 | "lockfileVersion": 3,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "name": "cordova-plugin-file-tests",
9 | "version": "8.1.4-dev",
10 | "license": "Apache-2.0"
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/tests/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cordova-plugin-file-tests",
3 | "version": "8.1.4-dev",
4 | "description": "",
5 | "cordova": {
6 | "id": "cordova-plugin-file-tests",
7 | "platforms": [
8 | "android"
9 | ]
10 | },
11 | "keywords": [
12 | "ecosystem:cordova",
13 | "cordova-android"
14 | ],
15 | "author": "",
16 | "license": "Apache-2.0"
17 | }
18 |
--------------------------------------------------------------------------------
/tests/plugin.xml:
--------------------------------------------------------------------------------
1 |
2 |
20 |
21 |
25 |
26 | Cordova File Plugin Tests
27 | Apache 2.0
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
39 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/tests/src/android/TestContentProvider.java:
--------------------------------------------------------------------------------
1 | /*
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. See the NOTICE file
4 | distributed with this work for additional information
5 | regarding copyright ownership. The ASF licenses this file
6 | to you under the Apache License, Version 2.0 (the
7 | "License"); you may not use this file except in compliance
8 | with the License. You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing,
13 | software distributed under the License is distributed on an
14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | KIND, either express or implied. See the License for the
16 | specific language governing permissions and limitations
17 | under the License.
18 | */
19 | package org.apache.cordova.file.test;
20 |
21 | import android.content.ContentProvider;
22 | import android.net.Uri;
23 | import android.content.res.AssetFileDescriptor;
24 | import android.content.res.AssetManager;
25 |
26 | import java.io.File;
27 | import java.io.FileInputStream;
28 | import java.io.FileNotFoundException;
29 | import android.content.ContentValues;
30 | import android.database.Cursor;
31 | import android.os.ParcelFileDescriptor;
32 |
33 | import org.apache.cordova.CordovaResourceApi;
34 |
35 | import java.io.IOException;
36 | import java.util.HashMap;
37 |
38 | public class TestContentProvider extends ContentProvider {
39 |
40 | @Override
41 | public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
42 | String fileName = uri.getQueryParameter("realPath");
43 | if (fileName == null) {
44 | fileName = uri.getPath();
45 | }
46 | if (fileName == null || fileName.length() < 1) {
47 | throw new FileNotFoundException();
48 | }
49 | CordovaResourceApi resourceApi = new CordovaResourceApi(getContext(), null);
50 | try {
51 | File f = File.createTempFile("test-content-provider", ".tmp");
52 | resourceApi.copyResource(Uri.parse("file:///android_asset" + fileName), Uri.fromFile(f));
53 | return ParcelFileDescriptor.open(f, ParcelFileDescriptor.MODE_READ_ONLY);
54 | } catch (FileNotFoundException e) {
55 | throw e;
56 | } catch (IOException e) {
57 | e.printStackTrace();
58 | throw new FileNotFoundException("IO error: " + e.toString());
59 | }
60 | }
61 |
62 | @Override
63 | public boolean onCreate() {
64 | return false;
65 | }
66 |
67 | @Override
68 | public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
69 | throw new UnsupportedOperationException();
70 | }
71 |
72 | @Override
73 | public String getType(Uri uri) {
74 | return "text/html";
75 | }
76 |
77 | @Override
78 | public Uri insert(Uri uri, ContentValues values) {
79 | throw new UnsupportedOperationException();
80 | }
81 |
82 | @Override
83 | public int delete(Uri uri, String selection, String[] selectionArgs) {
84 | throw new UnsupportedOperationException();
85 | }
86 |
87 | @Override
88 | public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
89 | throw new UnsupportedOperationException();
90 | }
91 |
92 |
93 | }
94 |
--------------------------------------------------------------------------------
/tests/www/fixtures/asset-test/asset-test.txt:
--------------------------------------------------------------------------------
1 | This file is here for testing purposes
--------------------------------------------------------------------------------
/www/DirectoryEntry.js:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Licensed to the Apache Software Foundation (ASF) under one
4 | * or more contributor license agreements. See the NOTICE file
5 | * distributed with this work for additional information
6 | * regarding copyright ownership. The ASF licenses this file
7 | * to you under the Apache License, Version 2.0 (the
8 | * "License"); you may not use this file except in compliance
9 | * with the License. You may obtain a copy of the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing,
14 | * software distributed under the License is distributed on an
15 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 | * KIND, either express or implied. See the License for the
17 | * specific language governing permissions and limitations
18 | * under the License.
19 | *
20 | */
21 |
22 | const argscheck = require('cordova/argscheck');
23 | const utils = require('cordova/utils');
24 | const exec = require('cordova/exec');
25 | const Entry = require('./Entry');
26 | const FileError = require('./FileError');
27 | const DirectoryReader = require('./DirectoryReader');
28 |
29 | /**
30 | * An interface representing a directory on the file system.
31 | *
32 | * {boolean} isFile always false (readonly)
33 | * {boolean} isDirectory always true (readonly)
34 | * {DOMString} name of the directory, excluding the path leading to it (readonly)
35 | * {DOMString} fullPath the absolute full path to the directory (readonly)
36 | * {FileSystem} filesystem on which the directory resides (readonly)
37 | */
38 | const DirectoryEntry = function (name, fullPath, fileSystem, nativeURL) {
39 | // add trailing slash if it is missing
40 | if ((fullPath) && !/\/$/.test(fullPath)) {
41 | fullPath += '/';
42 | }
43 | // add trailing slash if it is missing
44 | if (nativeURL && !/\/$/.test(nativeURL)) {
45 | nativeURL += '/';
46 | }
47 | DirectoryEntry.__super__.constructor.call(this, false, true, name, fullPath, fileSystem, nativeURL);
48 | };
49 |
50 | utils.extend(DirectoryEntry, Entry);
51 |
52 | /**
53 | * Creates a new DirectoryReader to read entries from this directory
54 | */
55 | DirectoryEntry.prototype.createReader = function () {
56 | return new DirectoryReader(this.toInternalURL());
57 | };
58 |
59 | /**
60 | * Creates or looks up a directory
61 | *
62 | * @param {DOMString} path either a relative or absolute path from this directory in which to look up or create a directory
63 | * @param {Flags} options to create or exclusively create the directory
64 | * @param {Function} successCallback is called with the new entry
65 | * @param {Function} errorCallback is called with a FileError
66 | */
67 | DirectoryEntry.prototype.getDirectory = function (path, options, successCallback, errorCallback) {
68 | argscheck.checkArgs('sOFF', 'DirectoryEntry.getDirectory', arguments);
69 | const fs = this.filesystem;
70 | const win = successCallback && function (result) {
71 | const entry = new DirectoryEntry(result.name, result.fullPath, fs, result.nativeURL);
72 | successCallback(entry);
73 | };
74 | const fail = errorCallback && function (code) {
75 | errorCallback(new FileError(code));
76 | };
77 | exec(win, fail, 'File', 'getDirectory', [this.toInternalURL(), path, options]);
78 | };
79 |
80 | /**
81 | * Deletes a directory and all of it's contents
82 | *
83 | * @param {Function} successCallback is called with no parameters
84 | * @param {Function} errorCallback is called with a FileError
85 | */
86 | DirectoryEntry.prototype.removeRecursively = function (successCallback, errorCallback) {
87 | argscheck.checkArgs('FF', 'DirectoryEntry.removeRecursively', arguments);
88 | const fail = errorCallback && function (code) {
89 | errorCallback(new FileError(code));
90 | };
91 | exec(successCallback, fail, 'File', 'removeRecursively', [this.toInternalURL()]);
92 | };
93 |
94 | /**
95 | * Creates or looks up a file
96 | *
97 | * @param {DOMString} path either a relative or absolute path from this directory in which to look up or create a file
98 | * @param {Flags} options to create or exclusively create the file
99 | * @param {Function} successCallback is called with the new entry
100 | * @param {Function} errorCallback is called with a FileError
101 | */
102 | DirectoryEntry.prototype.getFile = function (path, options, successCallback, errorCallback) {
103 | argscheck.checkArgs('sOFF', 'DirectoryEntry.getFile', arguments);
104 | const fs = this.filesystem;
105 | const win = successCallback && function (result) {
106 | const FileEntry = require('./FileEntry');
107 | const entry = new FileEntry(result.name, result.fullPath, fs, result.nativeURL);
108 | successCallback(entry);
109 | };
110 | const fail = errorCallback && function (code) {
111 | errorCallback(new FileError(code));
112 | };
113 | exec(win, fail, 'File', 'getFile', [this.toInternalURL(), path, options]);
114 | };
115 |
116 | module.exports = DirectoryEntry;
117 |
--------------------------------------------------------------------------------
/www/DirectoryReader.js:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Licensed to the Apache Software Foundation (ASF) under one
4 | * or more contributor license agreements. See the NOTICE file
5 | * distributed with this work for additional information
6 | * regarding copyright ownership. The ASF licenses this file
7 | * to you under the Apache License, Version 2.0 (the
8 | * "License"); you may not use this file except in compliance
9 | * with the License. You may obtain a copy of the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing,
14 | * software distributed under the License is distributed on an
15 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 | * KIND, either express or implied. See the License for the
17 | * specific language governing permissions and limitations
18 | * under the License.
19 | *
20 | */
21 |
22 | const exec = require('cordova/exec');
23 | const FileError = require('./FileError');
24 |
25 | /**
26 | * An interface that lists the files and directories in a directory.
27 | */
28 | function DirectoryReader (localURL) {
29 | this.localURL = localURL || null;
30 | this.hasReadEntries = false;
31 | }
32 |
33 | /**
34 | * Returns a list of entries from a directory.
35 | *
36 | * @param {Function} successCallback is called with a list of entries
37 | * @param {Function} errorCallback is called with a FileError
38 | */
39 | DirectoryReader.prototype.readEntries = function (successCallback, errorCallback) {
40 | // If we've already read and passed on this directory's entries, return an empty list.
41 | if (this.hasReadEntries) {
42 | successCallback([]);
43 | return;
44 | }
45 | const reader = this;
46 | const win = typeof successCallback !== 'function'
47 | ? null
48 | : function (result) {
49 | const retVal = [];
50 | for (let i = 0; i < result.length; i++) {
51 | let entry = null;
52 | if (result[i].isDirectory) {
53 | entry = new (require('./DirectoryEntry'))();
54 | } else if (result[i].isFile) {
55 | entry = new (require('./FileEntry'))();
56 | }
57 | entry.isDirectory = result[i].isDirectory;
58 | entry.isFile = result[i].isFile;
59 | entry.name = result[i].name;
60 | entry.fullPath = result[i].fullPath;
61 | entry.filesystem = new (require('./FileSystem'))(result[i].filesystemName);
62 | entry.nativeURL = result[i].nativeURL;
63 | retVal.push(entry);
64 | }
65 | reader.hasReadEntries = true;
66 | successCallback(retVal);
67 | };
68 | const fail = typeof errorCallback !== 'function'
69 | ? null
70 | : function (code) {
71 | errorCallback(new FileError(code));
72 | };
73 | exec(win, fail, 'File', 'readEntries', [this.localURL]);
74 | };
75 |
76 | module.exports = DirectoryReader;
77 |
--------------------------------------------------------------------------------
/www/Entry.js:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Licensed to the Apache Software Foundation (ASF) under one
4 | * or more contributor license agreements. See the NOTICE file
5 | * distributed with this work for additional information
6 | * regarding copyright ownership. The ASF licenses this file
7 | * to you under the Apache License, Version 2.0 (the
8 | * "License"); you may not use this file except in compliance
9 | * with the License. You may obtain a copy of the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing,
14 | * software distributed under the License is distributed on an
15 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 | * KIND, either express or implied. See the License for the
17 | * specific language governing permissions and limitations
18 | * under the License.
19 | *
20 | */
21 |
22 | const argscheck = require('cordova/argscheck');
23 | const exec = require('cordova/exec');
24 | const FileError = require('./FileError');
25 | const Metadata = require('./Metadata');
26 |
27 | /**
28 | * Represents a file or directory on the local file system.
29 | *
30 | * @param isFile
31 | * {boolean} true if Entry is a file (readonly)
32 | * @param isDirectory
33 | * {boolean} true if Entry is a directory (readonly)
34 | * @param name
35 | * {DOMString} name of the file or directory, excluding the path
36 | * leading to it (readonly)
37 | * @param fullPath
38 | * {DOMString} the absolute full path to the file or directory
39 | * (readonly)
40 | * @param fileSystem
41 | * {FileSystem} the filesystem on which this entry resides
42 | * (readonly)
43 | * @param nativeURL
44 | * {DOMString} an alternate URL which can be used by native
45 | * webview controls, for example media players.
46 | * (optional, readonly)
47 | */
48 | function Entry (isFile, isDirectory, name, fullPath, fileSystem, nativeURL) {
49 | this.isFile = !!isFile;
50 | this.isDirectory = !!isDirectory;
51 | this.name = name || '';
52 | this.fullPath = fullPath || '';
53 | this.filesystem = fileSystem || null;
54 | this.nativeURL = nativeURL || null;
55 | }
56 |
57 | /**
58 | * Look up the metadata of the entry.
59 | *
60 | * @param successCallback
61 | * {Function} is called with a Metadata object
62 | * @param errorCallback
63 | * {Function} is called with a FileError
64 | */
65 | Entry.prototype.getMetadata = function (successCallback, errorCallback) {
66 | argscheck.checkArgs('FF', 'Entry.getMetadata', arguments);
67 | const success = successCallback && function (entryMetadata) {
68 | const metadata = new Metadata({
69 | size: entryMetadata.size,
70 | modificationTime: entryMetadata.lastModifiedDate
71 | });
72 | successCallback(metadata);
73 | };
74 | const fail = errorCallback && function (code) {
75 | errorCallback(new FileError(code));
76 | };
77 | exec(success, fail, 'File', 'getFileMetadata', [this.toInternalURL()]);
78 | };
79 |
80 | /**
81 | * Set the metadata of the entry.
82 | *
83 | * @param successCallback
84 | * {Function} is called with a Metadata object
85 | * @param errorCallback
86 | * {Function} is called with a FileError
87 | * @param metadataObject
88 | * {Object} keys and values to set
89 | */
90 | Entry.prototype.setMetadata = function (successCallback, errorCallback, metadataObject) {
91 | argscheck.checkArgs('FFO', 'Entry.setMetadata', arguments);
92 | exec(successCallback, errorCallback, 'File', 'setMetadata', [this.toInternalURL(), metadataObject]);
93 | };
94 |
95 | /**
96 | * Move a file or directory to a new location.
97 | *
98 | * @param parent
99 | * {DirectoryEntry} the directory to which to move this entry
100 | * @param newName
101 | * {DOMString} new name of the entry, defaults to the current name
102 | * @param successCallback
103 | * {Function} called with the new DirectoryEntry object
104 | * @param errorCallback
105 | * {Function} called with a FileError
106 | */
107 | Entry.prototype.moveTo = function (parent, newName, successCallback, errorCallback) {
108 | argscheck.checkArgs('oSFF', 'Entry.moveTo', arguments);
109 | const fail = errorCallback && function (code) {
110 | errorCallback(new FileError(code));
111 | };
112 | const srcURL = this.toInternalURL();
113 | // entry name
114 | const name = newName || this.name;
115 | const success = function (entry) {
116 | if (entry) {
117 | if (successCallback) {
118 | // create appropriate Entry object
119 | const newFSName = entry.filesystemName || (entry.filesystem && entry.filesystem.name);
120 | const fs = newFSName ? new FileSystem(newFSName, { name: '', fullPath: '/' }) : new FileSystem(parent.filesystem.name, { name: '', fullPath: '/' });
121 | const result = (entry.isDirectory) ? new (require('./DirectoryEntry'))(entry.name, entry.fullPath, fs, entry.nativeURL) : new (require('cordova-plugin-file.FileEntry'))(entry.name, entry.fullPath, fs, entry.nativeURL);
122 | successCallback(result);
123 | }
124 | } else {
125 | // no Entry object returned
126 | if (fail) {
127 | fail(FileError.NOT_FOUND_ERR);
128 | }
129 | }
130 | };
131 |
132 | // copy
133 | exec(success, fail, 'File', 'moveTo', [srcURL, parent.toInternalURL(), name]);
134 | };
135 |
136 | /**
137 | * Copy a directory to a different location.
138 | *
139 | * @param parent
140 | * {DirectoryEntry} the directory to which to copy the entry
141 | * @param newName
142 | * {DOMString} new name of the entry, defaults to the current name
143 | * @param successCallback
144 | * {Function} called with the new Entry object
145 | * @param errorCallback
146 | * {Function} called with a FileError
147 | */
148 | Entry.prototype.copyTo = function (parent, newName, successCallback, errorCallback) {
149 | argscheck.checkArgs('oSFF', 'Entry.copyTo', arguments);
150 | const fail = errorCallback && function (code) {
151 | errorCallback(new FileError(code));
152 | };
153 | const srcURL = this.toInternalURL();
154 | // entry name
155 | const name = newName || this.name;
156 | // success callback
157 | const success = function (entry) {
158 | if (entry) {
159 | if (successCallback) {
160 | // create appropriate Entry object
161 | const newFSName = entry.filesystemName || (entry.filesystem && entry.filesystem.name);
162 | const fs = newFSName ? new FileSystem(newFSName, { name: '', fullPath: '/' }) : new FileSystem(parent.filesystem.name, { name: '', fullPath: '/' });
163 | const result = (entry.isDirectory) ? new (require('./DirectoryEntry'))(entry.name, entry.fullPath, fs, entry.nativeURL) : new (require('cordova-plugin-file.FileEntry'))(entry.name, entry.fullPath, fs, entry.nativeURL);
164 | successCallback(result);
165 | }
166 | } else {
167 | // no Entry object returned
168 | if (fail) {
169 | fail(FileError.NOT_FOUND_ERR);
170 | }
171 | }
172 | };
173 |
174 | // copy
175 | exec(success, fail, 'File', 'copyTo', [srcURL, parent.toInternalURL(), name]);
176 | };
177 |
178 | /**
179 | * Return a URL that can be passed across the bridge to identify this entry.
180 | */
181 | Entry.prototype.toInternalURL = function () {
182 | if (this.filesystem && this.filesystem.__format__) {
183 | return this.filesystem.__format__(this.fullPath, this.nativeURL);
184 | }
185 | };
186 |
187 | /**
188 | * Return a URL that can be used to identify this entry.
189 | * Use a URL that can be used to as the src attribute of a