9
9
import android .os .Build .VERSION_CODES ;
10
10
import android .os .Handler ;
11
11
import android .os .Looper ;
12
+ import android .util .Log ;
12
13
import androidx .annotation .NonNull ;
13
14
import com .google .common .util .concurrent .FutureCallback ;
14
15
import com .google .common .util .concurrent .Futures ;
15
16
import com .google .common .util .concurrent .SettableFuture ;
16
17
import com .google .common .util .concurrent .ThreadFactoryBuilder ;
17
18
import io .flutter .embedding .engine .plugins .FlutterPlugin ;
19
+ import io .flutter .plugin .common .BinaryMessenger ;
18
20
import io .flutter .plugin .common .MethodCall ;
19
21
import io .flutter .plugin .common .MethodChannel ;
20
22
import io .flutter .plugin .common .MethodChannel .MethodCallHandler ;
21
23
import io .flutter .plugin .common .MethodChannel .Result ;
24
+ import io .flutter .plugin .common .MethodCodec ;
25
+ import io .flutter .plugin .common .StandardMethodCodec ;
22
26
import io .flutter .util .PathUtils ;
23
27
import java .io .File ;
28
+ import java .lang .reflect .Constructor ;
29
+ import java .lang .reflect .Method ;
24
30
import java .util .ArrayList ;
25
31
import java .util .List ;
26
32
import java .util .concurrent .Callable ;
27
33
import java .util .concurrent .Executor ;
28
34
import java .util .concurrent .Executors ;
29
35
30
36
public class PathProviderPlugin implements FlutterPlugin , MethodCallHandler {
31
-
37
+ static final String TAG = "PathProviderPlugin" ;
32
38
private Context context ;
33
39
private MethodChannel channel ;
34
- private final Executor uiThreadExecutor = new UiThreadExecutor ();
35
- private final Executor executor =
36
- Executors .newSingleThreadExecutor (
37
- new ThreadFactoryBuilder ()
38
- .setNameFormat ("path-provider-background-%d" )
39
- .setPriority (Thread .NORM_PRIORITY )
40
- .build ());
40
+ private PathProviderImpl impl ;
41
+
42
+ private interface PathProviderImpl {
43
+ void getTemporaryDirectory (@ NonNull Result result );
44
+
45
+ void getApplicationDocumentsDirectory (@ NonNull Result result );
46
+
47
+ void getStorageDirectory (@ NonNull Result result );
48
+
49
+ void getExternalCacheDirectories (@ NonNull Result result );
50
+
51
+ void getExternalStorageDirectories (@ NonNull String directoryName , @ NonNull Result result );
52
+
53
+ void getApplicationSupportDirectory (@ NonNull Result result );
54
+ }
55
+
56
+ private class PathProviderPlatformThread implements PathProviderImpl {
57
+ private final Executor uiThreadExecutor = new UiThreadExecutor ();
58
+ private final Executor executor =
59
+ Executors .newSingleThreadExecutor (
60
+ new ThreadFactoryBuilder ()
61
+ .setNameFormat ("path-provider-background-%d" )
62
+ .setPriority (Thread .NORM_PRIORITY )
63
+ .build ());
64
+
65
+ public void getTemporaryDirectory (@ NonNull Result result ) {
66
+ executeInBackground (() -> getPathProviderTemporaryDirectory (), result );
67
+ }
68
+
69
+ public void getApplicationDocumentsDirectory (@ NonNull Result result ) {
70
+ executeInBackground (() -> getPathProviderApplicationDocumentsDirectory (), result );
71
+ }
72
+
73
+ public void getStorageDirectory (@ NonNull Result result ) {
74
+ executeInBackground (() -> getPathProviderStorageDirectory (), result );
75
+ }
76
+
77
+ public void getExternalCacheDirectories (@ NonNull Result result ) {
78
+ executeInBackground (() -> getPathProviderExternalCacheDirectories (), result );
79
+ }
80
+
81
+ public void getExternalStorageDirectories (
82
+ @ NonNull String directoryName , @ NonNull Result result ) {
83
+ executeInBackground (() -> getPathProviderExternalStorageDirectories (directoryName ), result );
84
+ }
85
+
86
+ public void getApplicationSupportDirectory (@ NonNull Result result ) {
87
+ executeInBackground (() -> PathProviderPlugin .this .getApplicationSupportDirectory (), result );
88
+ }
89
+
90
+ private <T > void executeInBackground (Callable <T > task , Result result ) {
91
+ final SettableFuture <T > future = SettableFuture .create ();
92
+ Futures .addCallback (
93
+ future ,
94
+ new FutureCallback <T >() {
95
+ public void onSuccess (T answer ) {
96
+ result .success (answer );
97
+ }
98
+
99
+ public void onFailure (Throwable t ) {
100
+ result .error (t .getClass ().getName (), t .getMessage (), null );
101
+ }
102
+ },
103
+ uiThreadExecutor );
104
+ executor .execute (
105
+ () -> {
106
+ try {
107
+ future .set (task .call ());
108
+ } catch (Throwable t ) {
109
+ future .setException (t );
110
+ }
111
+ });
112
+ }
113
+ }
114
+
115
+ private class PathProviderBackgroundThread implements PathProviderImpl {
116
+ public void getTemporaryDirectory (@ NonNull Result result ) {
117
+ result .success (getPathProviderTemporaryDirectory ());
118
+ }
119
+
120
+ public void getApplicationDocumentsDirectory (@ NonNull Result result ) {
121
+ result .success (getPathProviderApplicationDocumentsDirectory ());
122
+ }
123
+
124
+ public void getStorageDirectory (@ NonNull Result result ) {
125
+ result .success (getPathProviderStorageDirectory ());
126
+ }
127
+
128
+ public void getExternalCacheDirectories (@ NonNull Result result ) {
129
+ result .success (getPathProviderExternalCacheDirectories ());
130
+ }
131
+
132
+ public void getExternalStorageDirectories (
133
+ @ NonNull String directoryName , @ NonNull Result result ) {
134
+ result .success (getPathProviderExternalStorageDirectories (directoryName ));
135
+ }
136
+
137
+ public void getApplicationSupportDirectory (@ NonNull Result result ) {
138
+ result .success (PathProviderPlugin .this .getApplicationSupportDirectory ());
139
+ }
140
+ }
41
141
42
142
public PathProviderPlugin () {}
43
143
144
+ private void setup (BinaryMessenger messenger , Context context ) {
145
+ String channelName = "plugins.flutter.io/path_provider" ;
146
+ // TODO(gaaclarke): Remove reflection guard when https://github.com/flutter/engine/pull/29147
147
+ // becomes available on the stable branch.
148
+ try {
149
+ Class methodChannelClass = Class .forName ("io.flutter.plugin.common.MethodChannel" );
150
+ Class taskQueueClass = Class .forName ("io.flutter.plugin.common.BinaryMessenger$TaskQueue" );
151
+ Method makeBackgroundTaskQueue = messenger .getClass ().getMethod ("makeBackgroundTaskQueue" );
152
+ Object taskQueue = makeBackgroundTaskQueue .invoke (messenger );
153
+ Constructor <MethodChannel > constructor =
154
+ methodChannelClass .getConstructor (
155
+ BinaryMessenger .class , String .class , MethodCodec .class , taskQueueClass );
156
+ channel =
157
+ constructor .newInstance (messenger , channelName , StandardMethodCodec .INSTANCE , taskQueue );
158
+ impl = new PathProviderBackgroundThread ();
159
+ Log .d (TAG , "Use TaskQueues." );
160
+ } catch (Exception ex ) {
161
+ channel = new MethodChannel (messenger , channelName );
162
+ impl = new PathProviderPlatformThread ();
163
+ Log .d (TAG , "Don't use TaskQueues." );
164
+ }
165
+ this .context = context ;
166
+ channel .setMethodCallHandler (this );
167
+ }
168
+
44
169
@ SuppressWarnings ("deprecation" )
45
170
public static void registerWith (io .flutter .plugin .common .PluginRegistry .Registrar registrar ) {
46
171
PathProviderPlugin instance = new PathProviderPlugin ();
47
- instance .channel = new MethodChannel (registrar .messenger (), "plugins.flutter.io/path_provider" );
48
- instance .context = registrar .context ();
49
- instance .channel .setMethodCallHandler (instance );
172
+ instance .setup (registrar .messenger (), registrar .context ());
50
173
}
51
174
52
175
@ Override
53
176
public void onAttachedToEngine (@ NonNull FlutterPluginBinding binding ) {
54
- channel = new MethodChannel (binding .getBinaryMessenger (), "plugins.flutter.io/path_provider" );
55
- context = binding .getApplicationContext ();
56
- channel .setMethodCallHandler (this );
177
+ setup (binding .getBinaryMessenger (), binding .getApplicationContext ());
57
178
}
58
179
59
180
@ Override
@@ -62,52 +183,28 @@ public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
62
183
channel = null ;
63
184
}
64
185
65
- private <T > void executeInBackground (Callable <T > task , Result result ) {
66
- final SettableFuture <T > future = SettableFuture .create ();
67
- Futures .addCallback (
68
- future ,
69
- new FutureCallback <T >() {
70
- public void onSuccess (T answer ) {
71
- result .success (answer );
72
- }
73
-
74
- public void onFailure (Throwable t ) {
75
- result .error (t .getClass ().getName (), t .getMessage (), null );
76
- }
77
- },
78
- uiThreadExecutor );
79
- executor .execute (
80
- () -> {
81
- try {
82
- future .set (task .call ());
83
- } catch (Throwable t ) {
84
- future .setException (t );
85
- }
86
- });
87
- }
88
-
89
186
@ Override
90
187
public void onMethodCall (MethodCall call , @ NonNull Result result ) {
91
188
switch (call .method ) {
92
189
case "getTemporaryDirectory" :
93
- executeInBackground (() -> getPathProviderTemporaryDirectory (), result );
190
+ impl . getTemporaryDirectory ( result );
94
191
break ;
95
192
case "getApplicationDocumentsDirectory" :
96
- executeInBackground (() -> getPathProviderApplicationDocumentsDirectory (), result );
193
+ impl . getApplicationDocumentsDirectory ( result );
97
194
break ;
98
195
case "getStorageDirectory" :
99
- executeInBackground (() -> getPathProviderStorageDirectory (), result );
196
+ impl . getStorageDirectory ( result );
100
197
break ;
101
198
case "getExternalCacheDirectories" :
102
- executeInBackground (() -> getPathProviderExternalCacheDirectories (), result );
199
+ impl . getExternalCacheDirectories ( result );
103
200
break ;
104
201
case "getExternalStorageDirectories" :
105
202
final Integer type = call .argument ("type" );
106
203
final String directoryName = StorageDirectoryMapper .androidType (type );
107
- executeInBackground (() -> getPathProviderExternalStorageDirectories ( directoryName ) , result );
204
+ impl . getExternalStorageDirectories ( directoryName , result );
108
205
break ;
109
206
case "getApplicationSupportDirectory" :
110
- executeInBackground (() -> getApplicationSupportDirectory (), result );
207
+ impl . getApplicationSupportDirectory (result );
111
208
break ;
112
209
default :
113
210
result .notImplemented ();
0 commit comments