Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Classes | Public Member Functions | Static Public Attributes | Protected Attributes | List of all members
io.flutter.embedding.engine.deferredcomponents.PlayStoreDeferredComponentManager Class Reference
Inheritance diagram for io.flutter.embedding.engine.deferredcomponents.PlayStoreDeferredComponentManager:
io.flutter.embedding.engine.deferredcomponents.DeferredComponentManager

Public Member Functions

 PlayStoreDeferredComponentManager ( @NonNull Context context, @Nullable FlutterJNI flutterJNI)
 
void setJNI (@NonNull FlutterJNI flutterJNI)
 
void setDeferredComponentChannel (@NonNull DeferredComponentChannel channel)
 
void installDeferredComponent (int loadingUnitId, @Nullable String componentName)
 
String getDeferredComponentInstallState (int loadingUnitId, @Nullable String componentName)
 
void loadAssets (int loadingUnitId, @NonNull String componentName)
 
void loadDartLibrary (int loadingUnitId, @NonNull String componentName)
 
boolean uninstallDeferredComponent (int loadingUnitId, @Nullable String componentName)
 
void destroy ()
 
- Public Member Functions inherited from io.flutter.embedding.engine.deferredcomponents.DeferredComponentManager
abstract void setJNI (FlutterJNI flutterJNI)
 
abstract void setDeferredComponentChannel (DeferredComponentChannel channel)
 
abstract void installDeferredComponent (int loadingUnitId, String componentName)
 
abstract String getDeferredComponentInstallState (int loadingUnitId, String componentName)
 
abstract void loadAssets (int loadingUnitId, String componentName)
 
abstract void loadDartLibrary (int loadingUnitId, String componentName)
 
abstract boolean uninstallDeferredComponent (int loadingUnitId, String componentName)
 

Static Public Attributes

static final String MAPPING_KEY
 

Protected Attributes

SparseArray< String > loadingUnitIdToComponentNames
 
SparseArray< String > loadingUnitIdToSharedLibraryNames
 

Detailed Description

Flutter default implementation of DeferredComponentManager that downloads deferred component from the Google Play store as a dynamic feature module.

Definition at line 44 of file PlayStoreDeferredComponentManager.java.

Constructor & Destructor Documentation

◆ PlayStoreDeferredComponentManager()

io.flutter.embedding.engine.deferredcomponents.PlayStoreDeferredComponentManager.PlayStoreDeferredComponentManager ( @NonNull Context  context,
@Nullable FlutterJNI  flutterJNI 
)
inline

Definition at line 202 of file PlayStoreDeferredComponentManager.java.

203 {
204 this.context = context;
205 this.flutterJNI = flutterJNI;
206 this.flutterApplicationInfo = ApplicationInfoLoader.load(context);
207 splitInstallManager = SplitInstallManagerFactory.create(context);
208 listener = new FeatureInstallStateUpdatedListener();
209 splitInstallManager.registerListener(listener);
210 sessionIdToName = new SparseArray<>();
211 sessionIdToLoadingUnitId = new SparseIntArray();
212 sessionIdToState = new SparseArray<>();
213 nameToSessionId = new HashMap<>();
214
215 loadingUnitIdToComponentNames = new SparseArray<>();
216 loadingUnitIdToSharedLibraryNames = new SparseArray<>();
217 initLoadingUnitMappingToComponentNames();
218 }

Member Function Documentation

◆ destroy()

void io.flutter.embedding.engine.deferredcomponents.PlayStoreDeferredComponentManager.destroy ( )
inline

Cleans up and releases resources. This object is no longer usable after calling this method.

Implements io.flutter.embedding.engine.deferredcomponents.DeferredComponentManager.

Definition at line 493 of file PlayStoreDeferredComponentManager.java.

493 {
494 splitInstallManager.unregisterListener(listener);
495 channel = null;
496 flutterJNI = null;
497 }

◆ getDeferredComponentInstallState()

String io.flutter.embedding.engine.deferredcomponents.PlayStoreDeferredComponentManager.getDeferredComponentInstallState ( int  loadingUnitId,
@Nullable String  componentName 
)
inline

Definition at line 361 of file PlayStoreDeferredComponentManager.java.

362 {
363 String resolvedComponentName =
364 componentName != null ? componentName : loadingUnitIdToComponentNames.get(loadingUnitId);
365 if (resolvedComponentName == null) {
366 Log.e(
367 TAG, "Deferred component name was null and could not be resolved from loading unit id.");
368 return "unknown";
369 }
370 if (!nameToSessionId.containsKey(resolvedComponentName)) {
371 if (splitInstallManager.getInstalledModules().contains(resolvedComponentName)) {
372 return "installedPendingLoad";
373 }
374 return "unknown";
375 }
376 int sessionId = nameToSessionId.get(resolvedComponentName);
377 return sessionIdToState.get(sessionId);
378 }
void Log(const char *format,...) SK_PRINTF_LIKE(1

◆ installDeferredComponent()

void io.flutter.embedding.engine.deferredcomponents.PlayStoreDeferredComponentManager.installDeferredComponent ( int  loadingUnitId,
@Nullable String  componentName 
)
inline

Definition at line 291 of file PlayStoreDeferredComponentManager.java.

291 {
292 String resolvedComponentName =
293 componentName != null ? componentName : loadingUnitIdToComponentNames.get(loadingUnitId);
294 if (resolvedComponentName == null) {
295 Log.e(
296 TAG, "Deferred component name was null and could not be resolved from loading unit id.");
297 return;
298 }
299
300 // Handle a loading unit that is included in the base module that does not need download.
301 if (resolvedComponentName.equals("") && loadingUnitId > 0) {
302 // No need to load assets as base assets are already loaded.
303 loadDartLibrary(loadingUnitId, resolvedComponentName);
304 return;
305 }
306
307 SplitInstallRequest request =
308 SplitInstallRequest.newBuilder().addModule(resolvedComponentName).build();
309
310 splitInstallManager
311 // Submits the request to install the module through the
312 // asynchronous startInstall() task. Your app needs to be
313 // in the foreground to submit the request.
314 .startInstall(request)
315 // Called when the install request is sent successfully. This is different than a successful
316 // install which is handled in FeatureInstallStateUpdatedListener.
317 .addOnSuccessListener(
318 sessionId -> {
319 sessionIdToName.put(sessionId, resolvedComponentName);
320 sessionIdToLoadingUnitId.put(sessionId, loadingUnitId);
321 if (nameToSessionId.containsKey(resolvedComponentName)) {
322 sessionIdToState.remove(nameToSessionId.get(resolvedComponentName));
323 }
324 nameToSessionId.put(resolvedComponentName, sessionId);
325 sessionIdToState.put(sessionId, "Requested");
326 })
327 .addOnFailureListener(
328 exception -> {
329 switch (((SplitInstallException) exception).getErrorCode()) {
330 case SplitInstallErrorCode.NETWORK_ERROR:
332 loadingUnitId,
333 "Install of deferred component module \""
334 + componentName
335 + "\" failed with a network error",
336 true);
337 break;
338 case SplitInstallErrorCode.MODULE_UNAVAILABLE:
340 loadingUnitId,
341 "Install of deferred component module \""
342 + componentName
343 + "\" failed as it is unavailable",
344 false);
345 break;
346 default:
348 loadingUnitId,
349 String.format(
350 "Install of deferred component module \"%s\" failed with error %d: %s",
351 componentName,
352 ((SplitInstallException) exception).getErrorCode(),
353 ((SplitInstallException) exception).getMessage()),
354 false);
355 break;
356 }
357 });
358 }
void deferredComponentInstallFailure(int loadingUnitId, @NonNull String error, boolean isTransient)

◆ loadAssets()

void io.flutter.embedding.engine.deferredcomponents.PlayStoreDeferredComponentManager.loadAssets ( int  loadingUnitId,
@NonNull String  componentName 
)
inline

Definition at line 380 of file PlayStoreDeferredComponentManager.java.

380 {
381 if (!verifyJNI()) {
382 return;
383 }
384 // Since android deferred component asset manager is handled through
385 // context, neither parameter is used here. Assets are stored in
386 // the apk's `assets` directory allowing them to be accessed by
387 // Android's AssetManager directly.
388 try {
389 context = context.createPackageContext(context.getPackageName(), 0);
390
391 AssetManager assetManager = context.getAssets();
392 flutterJNI.updateJavaAssetManager(assetManager, flutterApplicationInfo.flutterAssetsDir);
393 } catch (NameNotFoundException e) {
394 throw new RuntimeException(e);
395 }
396 }
void updateJavaAssetManager( @NonNull AssetManager assetManager, @NonNull String assetBundlePath)

◆ loadDartLibrary()

void io.flutter.embedding.engine.deferredcomponents.PlayStoreDeferredComponentManager.loadDartLibrary ( int  loadingUnitId,
@NonNull String  componentName 
)
inline

Definition at line 398 of file PlayStoreDeferredComponentManager.java.

398 {
399 if (!verifyJNI()) {
400 return;
401 }
402 // Loading unit must be specified and valid to load a dart library.
403 if (loadingUnitId < 0) {
404 return;
405 }
406
407 String aotSharedLibraryName = loadingUnitIdToSharedLibraryNames.get(loadingUnitId);
408 if (aotSharedLibraryName == null) {
409 // If the filename is not specified, we use dart's loading unit naming convention.
410 aotSharedLibraryName =
411 flutterApplicationInfo.aotSharedLibraryName + "-" + loadingUnitId + ".part.so";
412 }
413
414 // Possible values: armeabi, armeabi-v7a, arm64-v8a, x86, x86_64, mips, mips64
415 String abi = Build.SUPPORTED_ABIS[0];
416 String pathAbi = abi.replace("-", "_"); // abis are represented with underscores in paths.
417
418 // TODO(garyq): Optimize this apk/file discovery process to use less i/o and be more
419 // performant and robust.
420
421 // Search directly in APKs first
422 List<String> apkPaths = new ArrayList<>();
423 // If not found in APKs, we check in extracted native libs for the lib directly.
424 List<String> soPaths = new ArrayList<>();
425
426 Queue<File> searchFiles = new LinkedList<>();
427 // Downloaded modules are stored here
428 searchFiles.add(context.getFilesDir());
429 // The initial installed apks are provided by `sourceDirs` in ApplicationInfo.
430 // The jniLibs we want are in the splits not the baseDir. These
431 // APKs are only searched as a fallback, as base libs generally do not need
432 // to be fully path referenced.
433 for (String path : context.getApplicationInfo().splitSourceDirs) {
434 searchFiles.add(new File(path));
435 }
436
437 while (!searchFiles.isEmpty()) {
438 File file = searchFiles.remove();
439 if (file != null && file.isDirectory() && file.listFiles() != null) {
440 for (File f : file.listFiles()) {
441 searchFiles.add(f);
442 }
443 continue;
444 }
445 String name = file.getName();
446 // Special case for "split_config" since android base module non-master apks are
447 // initially installed with the "split_config" prefix/name.
448 if (name.endsWith(".apk")
449 && (name.startsWith(componentName) || name.startsWith("split_config"))
450 && name.contains(pathAbi)) {
451 apkPaths.add(file.getAbsolutePath());
452 continue;
453 }
454 if (name.equals(aotSharedLibraryName)) {
455 soPaths.add(file.getAbsolutePath());
456 }
457 }
458
459 List<String> searchPaths = new ArrayList<>();
460
461 // Add the bare filename as the first search path. In some devices, the so
462 // file can be dlopen-ed with just the file name.
463 searchPaths.add(aotSharedLibraryName);
464
465 for (String path : apkPaths) {
466 searchPaths.add(path + "!lib/" + abi + "/" + aotSharedLibraryName);
467 }
468 for (String path : soPaths) {
469 searchPaths.add(path);
470 }
471
472 flutterJNI.loadDartDeferredLibrary(
473 loadingUnitId, searchPaths.toArray(new String[searchPaths.size()]));
474 }
void add(sk_sp< SkIDChangeListener > listener) SK_EXCLUDES(fMutex)
void loadDartDeferredLibrary(int loadingUnitId, @NonNull String[] searchPaths)
const char * name
Definition fuchsia.cc:50
Build(configs, env, options)
Definition build.py:232

◆ setDeferredComponentChannel()

void io.flutter.embedding.engine.deferredcomponents.PlayStoreDeferredComponentManager.setDeferredComponentChannel ( @NonNull DeferredComponentChannel  channel)
inline

Definition at line 234 of file PlayStoreDeferredComponentManager.java.

234 {
235 this.channel = channel;
236 }

◆ setJNI()

void io.flutter.embedding.engine.deferredcomponents.PlayStoreDeferredComponentManager.setJNI ( @NonNull FlutterJNI  flutterJNI)
inline

Definition at line 220 of file PlayStoreDeferredComponentManager.java.

220 {
221 this.flutterJNI = flutterJNI;
222 }

◆ uninstallDeferredComponent()

boolean io.flutter.embedding.engine.deferredcomponents.PlayStoreDeferredComponentManager.uninstallDeferredComponent ( int  loadingUnitId,
@Nullable String  componentName 
)
inline

Definition at line 476 of file PlayStoreDeferredComponentManager.java.

476 {
477 String resolvedComponentName =
478 componentName != null ? componentName : loadingUnitIdToComponentNames.get(loadingUnitId);
479 if (resolvedComponentName == null) {
480 Log.e(
481 TAG, "Deferred component name was null and could not be resolved from loading unit id.");
482 return false;
483 }
484 List<String> modulesToUninstall = new ArrayList<>();
485 modulesToUninstall.add(resolvedComponentName);
486 splitInstallManager.deferredUninstall(modulesToUninstall);
487 if (nameToSessionId.get(resolvedComponentName) != null) {
488 sessionIdToState.delete(nameToSessionId.get(resolvedComponentName));
489 }
490 return true;
491 }

Member Data Documentation

◆ loadingUnitIdToComponentNames

SparseArray<String> io.flutter.embedding.engine.deferredcomponents.PlayStoreDeferredComponentManager.loadingUnitIdToComponentNames
protected

Definition at line 62 of file PlayStoreDeferredComponentManager.java.

◆ loadingUnitIdToSharedLibraryNames

SparseArray<String> io.flutter.embedding.engine.deferredcomponents.PlayStoreDeferredComponentManager.loadingUnitIdToSharedLibraryNames
protected

Definition at line 63 of file PlayStoreDeferredComponentManager.java.

◆ MAPPING_KEY

final String io.flutter.embedding.engine.deferredcomponents.PlayStoreDeferredComponentManager.MAPPING_KEY
static
Initial value:
=
DeferredComponentManager.class.getName() + ".loadingUnitMapping"

Definition at line 47 of file PlayStoreDeferredComponentManager.java.


The documentation for this class was generated from the following file: