signature:
public class ShadowEnvironment { /** * Adds a directory to list returned by { @ link ShadowUserEnvironment # getExternalDirs ( ) } .
 * @ param path the external dir to add */
public static File addExternalDir ( String path ) { } }

implementation: Path externalFileDir ; if ( path == null ) { externalFileDir = null ; } else { try { if ( tmpExternalFilesDirBase == null ) { tmpExternalFilesDirBase = RuntimeEnvironment . getTempDirectory ( ) . create ( "external-files-base" ) ; } externalFileDir = tmpExternalFilesDirBase . resolve ( path ) ; Files . createDirectories ( externalFileDir ) ; externalDirs . add ( externalFileDir . toFile ( ) ) ; } catch ( IOException e ) { throw new RuntimeException ( "Could not create external files dir" , e ) ; } } if ( RuntimeEnvironment . getApiLevel ( ) >= JELLY_BEAN_MR1 && RuntimeEnvironment . getApiLevel ( ) < KITKAT ) { if ( externalDirs . size ( ) == 1 && externalFileDir != null ) { Environment . UserEnvironment userEnvironment = ReflectionHelpers . getStaticField ( Environment . class , "sCurrentUser" ) ; reflector ( _UserEnvironment_ . class , userEnvironment ) . setExternalStorageAndroidData ( externalFileDir . toFile ( ) ) ; } } else if ( RuntimeEnvironment . getApiLevel ( ) >= KITKAT && RuntimeEnvironment . getApiLevel ( ) < M ) { Environment . UserEnvironment userEnvironment = ReflectionHelpers . getStaticField ( Environment . class , "sCurrentUser" ) ; reflector ( _UserEnvironment_ . class , userEnvironment ) . setExternalDirsForApp ( externalDirs . toArray ( new File [ 0 ] ) ) ; } if ( externalFileDir == null ) { return null ; } return externalFileDir . toFile ( ) ;


signature:
public class ShadowEnvironment { /** * Sets the { @ link # getExternalStorageState ( File ) } for given directory .
 * @ param externalStorageState Value to return from { @ link # getExternalStorageState ( File ) } . */
public static void setExternalStorageState ( File directory , String state ) { } }

implementation: storageState . put ( directory . toPath ( ) , state ) ;


signature:
public class ShadowSensor { /** * Constructs a { @ link Sensor } with a given type . */
public static Sensor newInstance ( int type ) { } }

implementation: Sensor sensor = Shadow . newInstanceOf ( Sensor . class ) ; reflector ( _Sensor_ . class , sensor ) . setTypeCompat ( type ) ; return sensor ;


signature:
public class ShadowSensor { /** * Controls the return value of { @ link Sensor # isWakeUpSensor ( ) } . */
public void setWakeUpFlag ( boolean wakeup ) { } }

implementation: int wakeUpSensorMask = reflector ( _Sensor_ . class ) . getWakeUpSensorFlag ( ) ; if ( wakeup ) { setMask ( wakeUpSensorMask ) ; } else { clearMask ( wakeUpSensorMask ) ; }


signature:
public class LocalUiController { /** * TODO ( b / 80130000 ) : implementation copied from espresso ' s UIControllerImpl . Refactor code into common location */
@ Override public boolean injectString ( String str ) throws InjectEventSecurityException { } }

implementation:
checkNotNull ( str ) ; checkState ( Looper . myLooper ( ) == Looper . getMainLooper ( ) , "Expecting to be on main thread!" ) ; // No - op if string is empty .
if ( str . isEmpty ( ) ) { Log . w ( TAG , "Supplied string is empty resulting in no-op (nothing is typed)." ) ; return true ; } boolean eventInjected = false ; KeyCharacterMap keyCharacterMap = getKeyCharacterMap ( ) ; // TODO ( b / 80130875 ) : Investigate why not use ( as suggested in javadoc of
// keyCharacterMap . getEvents ) :
// http : / / developer . android . com / reference / android / view / KeyEvent . html # KeyEvent ( long ,
// java . lang . String , int , int )
KeyEvent [ ] events = keyCharacterMap . getEvents ( str . toCharArray ( ) ) ; if ( events == null ) { throw new RuntimeException ( String . format ( "Failed to get key events for string %s (i.e. current IME does not understand how to" + " translate the string into key events). As a workaround, you can use" + " replaceText action to set the text directly in the EditText field." , str ) ) ; } Log . d ( TAG , String . format ( "Injecting string: \"%s\"" , str ) ) ; for ( KeyEvent event : events ) { checkNotNull ( event , String . format ( "Failed to get event for character (%c) with key code (%s)" , event . getKeyCode ( ) , event . getUnicodeChar ( ) ) ) ; eventInjected = false ; for ( int attempts = 0 ; ! eventInjected && attempts < 4 ; attempts ++ ) { // We have to change the time of an event before injecting it because
// all KeyEvents returned by KeyCharacterMap . getEvents ( ) have the same
// time stamp and the system rejects too old events . Hence , it is
// possible for an event to become stale before it is injected if it
// takes too long to inject the preceding ones .
event = KeyEvent . changeTimeRepeat ( event , SystemClock . uptimeMillis ( ) , 0 ) ; eventInjected = injectKeyEvent ( event ) ; } if ( ! eventInjected ) { Log . e ( TAG , String . format ( "Failed to inject event for character (%c) with key code (%s)" , event . getUnicodeChar ( ) , event . getKeyCode ( ) ) ) ; break ; } } return eventInjected ;


signature:
public class ShadowCaptureResult { /** * Obtain a property of the CaptureResult . */
@ Implementation @ Nullable @ SuppressWarnings ( "unchecked" ) protected < T > T get ( Key < T > key ) { } }

implementation: return ( T ) resultsKeyToValue . get ( key ) ;


signature:
public class ShadowCaptureResult { /** * Sets the value for a given key .
 * @ throws IllegalArgumentException if there ' s an existing value for the key . */
public < T > void set ( Key < T > key , T value ) { } }

implementation: Preconditions . checkArgument ( ! resultsKeyToValue . containsKey ( key ) ) ; resultsKeyToValue . put ( key , value ) ;


signature:
public class ShadowEventLog { /** * Writes an event log message , returning an approximation of the bytes written . */
@ Implementation protected static int writeEvent ( int tag , String str ) { } }

implementation: if ( str == null ) { str = NULL_PLACE_HOLDER ; } addEvent ( new EventBuilder ( tag , str ) . build ( ) ) ; return Integer . BYTES + str . length ( ) ;


signature:
public class ShadowEventLog { /** * Writes an event log message , returning an approximation of the bytes written . */
@ Implementation protected static int writeEvent ( int tag , Object ... list ) { } }

implementation:
if ( list == null ) { // This matches how the real android code handles nulls
return writeEvent ( tag , ( String ) null ) ; } addEvent ( new EventBuilder ( tag , list ) . build ( ) ) ; return Integer . BYTES + list . length * Integer . BYTES ;


signature:
public class ShadowEventLog { /** * Writes an event log message , returning an approximation of the bytes written . */
@ Implementation protected static int writeEvent ( int tag , int value ) { } }

implementation: addEvent ( new EventBuilder ( tag , value ) . build ( ) ) ; return Integer . BYTES + Integer . BYTES ;


signature:
public class ShadowEventLog { /** * Writes an event log message , returning an approximation of the bytes written . */
@ Implementation ( minSdk = VERSION_CODES . M ) protected static int writeEvent ( int tag , float value ) { } }

implementation: addEvent ( new EventBuilder ( tag , value ) . build ( ) ) ; return Integer . BYTES + Float . BYTES ;


signature:
public class ShadowArscAssetManager { /** * Returns true if the resource was found , filling in mRetStringBlock and
 * mRetData . */
@ Implementation @ HiddenApi protected final int loadResourceBagValue ( int ident , int bagEntryId , TypedValue outValue , boolean resolve ) { } }

implementation: CppAssetManager am = assetManagerForJavaObject ( ) ; if ( am == null ) { return 0 ; } final ResTable res = am . getResources ( ) ; return loadResourceBagValueInternal ( ident , bagEntryId , outValue , resolve , res ) ;


signature:
public class ShadowArscAssetManager { /** * # define PRIx32 " x " */
@ HiddenApi @ Implementation ( maxSdk = KITKAT_WATCH ) protected static void applyStyle ( int themeToken , int defStyleAttr , int defStyleRes , int xmlParserToken , int [ ] attrs , int [ ] outValues , int [ ] outIndices ) { } }

implementation: applyStyle ( ( long ) themeToken , defStyleAttr , defStyleRes , ( long ) xmlParserToken , attrs , outValues , outIndices ) ;


signature:
public class ShadowArscAssetManager { /** * int getThemeChangingConfigurations ( long theme ) ; */
@ HiddenApi @ Implementation protected final Number openXmlAssetNative ( int cookie , String fileName ) throws FileNotFoundException { } }

implementation:
CppAssetManager am = assetManagerForJavaObject ( ) ; if ( am == null ) { return RuntimeEnvironment . castNativePtr ( 0 ) ; } ALOGV ( "openXmlAsset in %s (Java object %s)\n" , am , ShadowArscAssetManager . class ) ; String fileName8 = fileName ; if ( fileName8 == null ) { return RuntimeEnvironment . castNativePtr ( 0 ) ; } int assetCookie = cookie ; Asset a ; if ( isTruthy ( assetCookie ) ) { a = am . openNonAsset ( assetCookie , fileName8 , AccessMode . ACCESS_BUFFER ) ; } else { final Ref < Integer > assetCookieRef = new Ref < > ( assetCookie ) ; a = am . openNonAsset ( fileName8 , AccessMode . ACCESS_BUFFER , assetCookieRef ) ; assetCookie = assetCookieRef . get ( ) ; } if ( a == null ) { throw new FileNotFoundException ( fileName8 ) ; } final DynamicRefTable dynamicRefTable = am . getResources ( ) . getDynamicRefTableForCookie ( assetCookie ) ; ResXMLTree block = new ResXMLTree ( dynamicRefTable ) ; int err = block . setTo ( a . getBuffer ( true ) , ( int ) a . getLength ( ) , true ) ; a . close ( ) ; // delete a ;
if ( err != NO_ERROR ) { throw new FileNotFoundException ( "Corrupt XML binary file" ) ; } return RuntimeEnvironment . castNativePtr ( Registries . NATIVE_RES_XML_TREES . register ( block ) ) ;


signature: public class ShadowArscAssetManager { @ HiddenApi @ Implementation protected int getStringBlockCount ( ) { } }

implementation: CppAssetManager am = assetManagerForJavaObject ( ) ; if ( am == null ) { return 0 ; } return am . getResources ( ) . getTableCount ( ) ;


signature:
public class ShadowLegacyLooper { /** * Enqueue a task to be run later .
 * @ param runnable the task to be run
 * @ param delayMillis how many milliseconds into the ( virtual ) future to run it
 * @ return true if the runnable is enqueued
 * @ see android . os . Handler # postDelayed ( Runnable , long )
 * @ deprecated Use a { @ link android . os . Handler } instance to post to a looper . */
@ Override @ Deprecated public boolean post ( Runnable runnable , long delayMillis ) { } }

implementation: if ( ! quit ) { getScheduler ( ) . postDelayed ( runnable , delayMillis , TimeUnit . MILLISECONDS ) ; return true ; } else { return false ; }


signature:
public class ShadowLegacyLooper { /** * Enqueue a task to be run ahead of all other delayed tasks .
 * @ param runnable the task to be run
 * @ return true if the runnable is enqueued
 * @ see android . os . Handler # postAtFrontOfQueue ( Runnable )
 * @ deprecated Use a { @ link android . os . Handler } instance to post to a looper . */
@ Override @ Deprecated public boolean postAtFrontOfQueue ( Runnable runnable ) { } }

implementation: if ( ! quit ) { getScheduler ( ) . postAtFrontOfQueue ( runnable ) ; return true ; } else { return false ; }


signature:
public class ShadowPackageManager { /** * Makes sure that given activity exists .
 * If the activity doesn ' t exist yet , it will be created with { @ code applicationInfo } set to an
 * existing application , or if it doesn ' t exist , a new package will be created .
 * @ return existing or newly created activity info . */
public ActivityInfo addActivityIfNotPresent ( ComponentName componentName ) { } }

implementation: return addComponent ( activityFilters , p -> p . activities , ( p , a ) -> p . activities = a , updateName ( componentName , new ActivityInfo ( ) ) , false ) ;


signature:
public class ShadowPackageManager { /** * Makes sure that given service exists .
 * If the service doesn ' t exist yet , it will be created with { @ code applicationInfo } set to an
 * existing application , or if it doesn ' t exist , a new package will be created .
 * @ return existing or newly created service info . */
public ServiceInfo addServiceIfNotPresent ( ComponentName componentName ) { } }

implementation: return addComponent ( serviceFilters , p -> p . services , ( p , a ) -> p . services = a , updateName ( componentName , new ServiceInfo ( ) ) , false ) ;


signature:
public class ShadowPackageManager { /** * Makes sure that given receiver exists .
 * If the receiver doesn ' t exist yet , it will be created with { @ code applicationInfo } set to an
 * existing application , or if it doesn ' t exist , a new package will be created .
 * @ return existing or newly created receiver info . */
public ActivityInfo addReceiverIfNotPresent ( ComponentName componentName ) { } }

implementation: return addComponent ( receiverFilters , p -> p . receivers , ( p , a ) -> p . receivers = a , updateName ( componentName , new ActivityInfo ( ) ) , false ) ;


signature:
public class ShadowPackageManager { /** * Makes sure that given provider exists .
 * If the provider doesn ' t exist yet , it will be created with { @ code applicationInfo } set to an
 * existing application , or if it doesn ' t exist , a new package will be created .
 * @ return existing or newly created provider info . */
public ProviderInfo addProviderIfNotPresent ( ComponentName componentName ) { } }

implementation: return addComponent ( providerFilters , p -> p . providers , ( p , a ) -> p . providers = a , updateName ( componentName , new ProviderInfo ( ) ) , false ) ;


signature:
public class ShadowPackageManager { /** * Adds or updates given activity in the system .
 * If activity with the same { @ link ComponentInfo # name } and { @ code ComponentInfo # packageName }
 * exists it will be updated . Its { @ link ComponentInfo # applicationInfo } is always set to { @ link
 * ApplicationInfo } already existing in the system , but if no application exists a new one will
 * be created using { @ link ComponentInfo # applicationInfo } in this component . */
public void addOrUpdateActivity ( ActivityInfo activityInfo ) { } }

implementation: addComponent ( activityFilters , p -> p . activities , ( p , a ) -> p . activities = a , new ActivityInfo ( activityInfo ) , true ) ;


signature:
public class ShadowPackageManager { /** * Adds or updates given service in the system .
 * If service with the same { @ link ComponentInfo # name } and { @ code ComponentInfo # packageName }
 * exists it will be updated . Its { @ link ComponentInfo # applicationInfo } is always set to { @ link
 * ApplicationInfo } already existing in the system , but if no application exists a new one will be
 * created using { @ link ComponentInfo # applicationInfo } in this component . */
public void addOrUpdateService ( ServiceInfo serviceInfo ) { } }

implementation: addComponent ( serviceFilters , p -> p . services , ( p , a ) -> p . services = a , new ServiceInfo ( serviceInfo ) , true ) ;


signature:
public class ShadowPackageManager { /** * Adds or updates given broadcast receiver in the system .
 * If broadcast receiver with the same { @ link ComponentInfo # name } and { @ code
 * ComponentInfo # packageName } exists it will be updated . Its { @ link ComponentInfo # applicationInfo }
 * is always set to { @ link ApplicationInfo } already existing in the system , but if no
 * application exists a new one will be created using { @ link ComponentInfo # applicationInfo } in
 * this component . */
public void addOrUpdateReceiver ( ActivityInfo receiverInfo ) { } }

implementation: addComponent ( receiverFilters , p -> p . receivers , ( p , a ) -> p . receivers = a , new ActivityInfo ( receiverInfo ) , true ) ;


signature:
public class ShadowPackageManager { /** * Adds or updates given content provider in the system .
 * If content provider with the same { @ link ComponentInfo # name } and { @ code
 * ComponentInfo # packageName } exists it will be updated . Its { @ link ComponentInfo # applicationInfo }
 * is always set to { @ link ApplicationInfo } already existing in the system , but if no
 * application exists a new one will be created using { @ link ComponentInfo # applicationInfo } in
 * this component . */
public void addOrUpdateProvider ( ProviderInfo providerInfo ) { } }

implementation: addComponent ( providerFilters , p -> p . providers , ( p , a ) -> p . providers = a , new ProviderInfo ( providerInfo ) , true ) ;


signature:
public class ShadowPackageManager { /** * Removes activity from the package manager .
 * @ return the removed component or { @ code null } if no such component existed . */
@ Nullable public ActivityInfo removeActivity ( ComponentName componentName ) { } }

implementation: return removeComponent ( componentName , activityFilters , p -> p . activities , ( p , a ) -> p . activities = a ) ;


signature:
public class ShadowPackageManager { /** * Removes service from the package manager .
 * @ return the removed component or { @ code null } if no such component existed . */
@ Nullable public ServiceInfo removeService ( ComponentName componentName ) { } }

implementation: return removeComponent ( componentName , serviceFilters , p -> p . services , ( p , a ) -> p . services = a ) ;


signature:
public class ShadowPackageManager { /** * Removes content provider from the package manager .
 * @ return the removed component or { @ code null } if no such component existed . */
@ Nullable public ProviderInfo removeProvider ( ComponentName componentName ) { } }

implementation: return removeComponent ( componentName , providerFilters , p -> p . providers , ( p , a ) -> p . providers = a ) ;


signature:
public class ShadowPackageManager { /** * Removes broadcast receiver from the package manager .
 * @ return the removed component or { @ code null } if no such component existed . */
@ Nullable public ActivityInfo removeReceiver ( ComponentName componentName ) { } }

implementation: return removeComponent ( componentName , receiverFilters , p -> p . receivers , ( p , a ) -> p . receivers = a ) ;


signature:
public class ShadowPackageManager { /** * From com . android . server . pm . PackageManagerService . compareSignatures ( ) . */
static int compareSignature ( Signature [ ] signatures1 , Signature [ ] signatures2 ) { } }

implementation: if ( signatures1 == null ) { return ( signatures2 == null ) ? SIGNATURE_NEITHER_SIGNED : SIGNATURE_FIRST_NOT_SIGNED ; } if ( signatures2 == null ) { return SIGNATURE_SECOND_NOT_SIGNED ; } if ( signatures1 . length != signatures2 . length ) { return SIGNATURE_NO_MATCH ; } HashSet < Signature > signatures1set = new HashSet < > ( asList ( signatures1 ) ) ; HashSet < Signature > signatures2set = new HashSet < > ( asList ( signatures2 ) ) ; return signatures1set . equals ( signatures2set ) ? SIGNATURE_MATCH : SIGNATURE_NO_MATCH ;


signature:
public class ShadowPackageManager { /** * TODO ( christianw ) : reconcile with AndroidTestEnvironment . setUpPackageStorage */
private static void setUpPackageStorage ( ApplicationInfo applicationInfo ) { } }

implementation: if ( applicationInfo . sourceDir == null ) { applicationInfo . sourceDir = createTempDir ( applicationInfo . packageName + "-sourceDir" ) ; } if ( applicationInfo . dataDir == null ) { applicationInfo . dataDir = createTempDir ( applicationInfo . packageName + "-dataDir" ) ; } if ( applicationInfo . publicSourceDir == null ) { applicationInfo . publicSourceDir = applicationInfo . sourceDir ; } if ( RuntimeEnvironment . getApiLevel ( ) >= N ) { applicationInfo . credentialProtectedDataDir = createTempDir ( "userDataDir" ) ; applicationInfo . deviceProtectedDataDir = createTempDir ( "deviceDataDir" ) ; }


signature:
public class ShadowPackageManager { /** * Sets extra resolve infos for an intent .
 * Those entries are added to whatever might be in the manifest already .
 * Note that all resolve infos will have { @ link ResolveInfo # isDefault } field set to { @ code
 * true } to allow their resolution for implicit intents . If this is not what you want , then you
 * still have the reference to those ResolveInfos , and you can set the field back to { @ code
 * false } .
 * @ deprecated see the note on { @ link # addResolveInfoForIntent ( Intent , ResolveInfo ) } . */
@ Deprecated public void setResolveInfosForIntent ( Intent intent , List < ResolveInfo > info ) { } }

implementation: resolveInfoForIntent . remove ( intent ) ; for ( ResolveInfo resolveInfo : info ) { addResolveInfoForIntent ( intent , resolveInfo ) ; }


signature:
public class ShadowPackageManager { /** * Adds extra resolve info for an intent .
 * Note that this resolve info will have { @ link ResolveInfo # isDefault } field set to { @ code
 * true } to allow its resolution for implicit intents . If this is not what you want , then please
 * use { @ link # addResolveInfoForIntentNoDefaults } instead .
 * @ deprecated use { @ link # addIntentFilterForComponent } instead and if the component doesn ' t exist
 * add it using any of { @ link # installPackage } , { @ link # addOrUpdateActivity } , { @ link
 * # addActivityIfNotPresent } or their counterparts for other types of components . */
@ Deprecated public void addResolveInfoForIntent ( Intent intent , ResolveInfo info ) { } }

implementation:
info . isDefault = true ; ComponentInfo [ ] componentInfos = new ComponentInfo [ ] { info . activityInfo , info . serviceInfo , Build . VERSION . SDK_INT >= KITKAT ? info . providerInfo : null } ; for ( ComponentInfo component : componentInfos ) { if ( component != null && component . applicationInfo != null ) { component . applicationInfo . flags |= ApplicationInfo . FLAG_INSTALLED ; if ( component . applicationInfo . processName == null ) { component . applicationInfo . processName = component . applicationInfo . packageName ; } } } if ( info . match == 0 ) { info . match = Integer . MAX_VALUE ; // make sure , that this is as good match as possible .
} addResolveInfoForIntentNoDefaults ( intent , info ) ;


signature:
public class ShadowPackageManager { /** * Adds the { @ code info } as { @ link ResolveInfo } for the intent but without applying any default
 * values .
 * In particular it will not make the { @ link ResolveInfo # isDefault } field { @ code true } , that
 * means that this resolve info will not resolve for { @ link Intent # resolveActivity } and { @ link
 * Context # startActivity } .
 * @ deprecated see the note on { @ link # addResolveInfoForIntent ( Intent , ResolveInfo ) } . */
@ Deprecated public void addResolveInfoForIntentNoDefaults ( Intent intent , ResolveInfo info ) { } }

implementation: Preconditions . checkNotNull ( info ) ; List < ResolveInfo > infoList = resolveInfoForIntent . get ( intent ) ; if ( infoList == null ) { infoList = new ArrayList < > ( ) ; resolveInfoForIntent . put ( intent , infoList ) ; } infoList . add ( info ) ;


signature:
public class ShadowPackageManager { /** * Removes { @ link ResolveInfo } s registered using { @ link # addResolveInfoForIntent } .
 * @ deprecated see note on { @ link # addResolveInfoForIntent ( Intent , ResolveInfo ) } . */
@ Deprecated public void removeResolveInfosForIntent ( Intent intent , String packageName ) { } }

implementation: List < ResolveInfo > infoList = resolveInfoForIntent . get ( intent ) ; if ( infoList == null ) { infoList = new ArrayList < > ( ) ; resolveInfoForIntent . put ( intent , infoList ) ; } for ( Iterator < ResolveInfo > iterator = infoList . iterator ( ) ; iterator . hasNext ( ) ; ) { ResolveInfo resolveInfo = iterator . next ( ) ; if ( getPackageName ( resolveInfo ) . equals ( packageName ) ) { iterator . remove ( ) ; } }


signature:
public class ShadowPackageManager { /** * Return the flags set in call to { @ link
 * android . app . ApplicationPackageManager # setComponentEnabledSetting ( ComponentName , int , int ) } .
 * @ param componentName The component name .
 * @ return The flags . */
public int getComponentEnabledSettingFlags ( ComponentName componentName ) { } }

implementation: ComponentState state = componentList . get ( componentName ) ; return state != null ? state . flags : 0 ;


signature:
public class ShadowPackageManager { /** * Installs a package with the { @ link PackageManager } .
 * In order to create PackageInfo objects in a valid state please use { @ link
 * androidx . test . core . content . pm . PackageInfoBuilder } .
 * This method automatically simulates instalation of a package in the system , so it adds a
 * flag { @ link ApplicationInfo # FLAG _ INSTALLED } to the application info and makes sure it exits . It
 * will update applicationInfo in package components as well .
 * If you don ' t want the package to be installed , use { @ link # addPackageNoDefaults } instead . */
public void installPackage ( PackageInfo packageInfo ) { } }

implementation: ApplicationInfo appInfo = packageInfo . applicationInfo ; if ( appInfo == null ) { appInfo = new ApplicationInfo ( ) ; packageInfo . applicationInfo = appInfo ; } if ( appInfo . packageName == null ) { appInfo . packageName = packageInfo . packageName ; } if ( appInfo . processName == null ) { appInfo . processName = appInfo . packageName ; } appInfo . flags |= ApplicationInfo . FLAG_INSTALLED ; ComponentInfo [ ] [ ] componentInfoArrays = new ComponentInfo [ ] [ ] { packageInfo . activities , packageInfo . services , packageInfo . providers , packageInfo . receivers , } ; int uniqueNameCounter = 0 ; for ( ComponentInfo [ ] componentInfos : componentInfoArrays ) { if ( componentInfos == null ) { continue ; } for ( ComponentInfo componentInfo : componentInfos ) { if ( componentInfo . name == null ) { componentInfo . name = appInfo . packageName + ".DefaultName" + uniqueNameCounter ++ ; componentInfo . packageName = packageInfo . packageName ; } componentInfo . applicationInfo = appInfo ; componentInfo . packageName = appInfo . packageName ; if ( componentInfo . processName == null ) { componentInfo . processName = appInfo . processName ; } } } addPackageNoDefaults ( packageInfo ) ;


signature:
public class ShadowPackageManager { /** * Adds a package to the { @ link PackageManager } , but doesn ' t set any default values on it .
 * Right now it will not set { @ link ApplicationInfo # FLAG _ INSTALLED } flag on its application , so
 * if not set explicitly , it will be treated as not installed . */
public void addPackageNoDefaults ( PackageInfo packageInfo ) { } }

implementation: PackageStats packageStats = new PackageStats ( packageInfo . packageName ) ; addPackage ( packageInfo , packageStats ) ;


signature:
public class ShadowPackageManager { /** * Installs a package with its stats with the { @ link PackageManager } .
 * This method doesn ' t add any defaults to the { @ code packageInfo } parameters . You should make
 * sure it is valid ( see { @ link # installPackage ( PackageInfo ) } ) . */
public synchronized void addPackage ( PackageInfo packageInfo , PackageStats packageStats ) { } }

implementation: if ( packageInfo . applicationInfo != null && ( packageInfo . applicationInfo . flags & ApplicationInfo . FLAG_INSTALLED ) == 0 ) { Log . w ( TAG , "Adding not installed package: " + packageInfo . packageName ) ; } Preconditions . checkArgument ( packageInfo . packageName . equals ( packageStats . packageName ) ) ; packageInfos . put ( packageInfo . packageName , packageInfo ) ; packageStatsMap . put ( packageInfo . packageName , packageStats ) ; packageSettings . put ( packageInfo . packageName , new PackageSetting ( ) ) ; applicationEnabledSettingMap . put ( packageInfo . packageName , PackageManager . COMPONENT_ENABLED_STATE_DEFAULT ) ; if ( packageInfo . applicationInfo != null ) { namesForUid . put ( packageInfo . applicationInfo . uid , packageInfo . packageName ) ; }


signature:
public class ShadowPackageManager { /** * Uninstalls the package from the system in a way , that will allow its discovery through { @ link
 * PackageManager # MATCH _ UNINSTALLED _ PACKAGES } . */
public void deletePackage ( String packageName ) { } }

implementation: deletedPackages . add ( packageName ) ; packageInfos . remove ( packageName ) ; mapForPackage ( activityFilters , packageName ) . clear ( ) ; mapForPackage ( serviceFilters , packageName ) . clear ( ) ; mapForPackage ( providerFilters , packageName ) . clear ( ) ; mapForPackage ( receiverFilters , packageName ) . clear ( ) ;


signature:
public class ShadowPackageManager { /** * Runs the callbacks pending from calls to { @ link PackageManager # deletePackage ( String ,
 * IPackageDeleteObserver , int ) } */
public void doPendingUninstallCallbacks ( ) { } }

implementation: boolean hasDeletePackagesPermission = false ; String [ ] requestedPermissions = packageInfos . get ( RuntimeEnvironment . application . getPackageName ( ) ) . requestedPermissions ; if ( requestedPermissions != null ) { for ( String permission : requestedPermissions ) { if ( Manifest . permission . DELETE_PACKAGES . equals ( permission ) ) { hasDeletePackagesPermission = true ; break ; } } } for ( String packageName : pendingDeleteCallbacks . keySet ( ) ) { int resultCode = PackageManager . DELETE_FAILED_INTERNAL_ERROR ; PackageInfo removed = packageInfos . get ( packageName ) ; if ( hasDeletePackagesPermission && removed != null ) { deletePackage ( packageName ) ; resultCode = PackageManager . DELETE_SUCCEEDED ; } try { pendingDeleteCallbacks . get ( packageName ) . packageDeleted ( packageName , resultCode ) ; } catch ( RemoteException e ) { throw new RuntimeException ( e ) ; } } pendingDeleteCallbacks . clear ( ) ;


signature:
public class ShadowPackageManager { /** * Internal use only .
 * @ param appPackage */
public void addPackageInternal ( Package appPackage ) { } }

implementation: int flags = GET_ACTIVITIES | GET_RECEIVERS | GET_SERVICES | GET_PROVIDERS | GET_INSTRUMENTATION | GET_INTENT_FILTERS | GET_SIGNATURES | GET_RESOLVED_FILTER | GET_META_DATA | GET_GIDS | MATCH_DISABLED_COMPONENTS | GET_SHARED_LIBRARY_FILES | GET_URI_PERMISSION_PATTERNS | GET_PERMISSIONS | MATCH_UNINSTALLED_PACKAGES | GET_CONFIGURATIONS | MATCH_DISABLED_UNTIL_USED_COMPONENTS | MATCH_DIRECT_BOOT_UNAWARE | MATCH_DIRECT_BOOT_AWARE ; for ( PermissionGroup permissionGroup : appPackage . permissionGroups ) { PermissionGroupInfo permissionGroupInfo = PackageParser . generatePermissionGroupInfo ( permissionGroup , flags ) ; addPermissionGroupInfo ( permissionGroupInfo ) ; } PackageInfo packageInfo = reflector ( _PackageParser_ . class ) . generatePackageInfo ( appPackage , new int [ ] { 0 } , flags , 0 , 0 ) ; packageInfo . applicationInfo . uid = Process . myUid ( ) ; packageInfo . applicationInfo . dataDir = createTempDir ( packageInfo . packageName + "-dataDir" ) ; installPackage ( packageInfo ) ; addFilters ( activityFilters , appPackage . activities ) ; addFilters ( serviceFilters , appPackage . services ) ; addFilters ( providerFilters , appPackage . providers ) ; addFilters ( receiverFilters , appPackage . receivers ) ;


signature:
public class ShadowPackageManager { /** * Add intent filter for given activity .
 * @ throws NameNotFoundException if component with given name doesn ' t exist . */
public void addIntentFilterForActivity ( ComponentName componentName , IntentFilter filter ) throws NameNotFoundException { } }

implementation: addIntentFilterForComponent ( componentName , filter , activityFilters ) ;


signature:
public class ShadowPackageManager { /** * Add intent filter for given service .
 * @ throws NameNotFoundException if component with given name doesn ' t exist . */
public void addIntentFilterForService ( ComponentName componentName , IntentFilter filter ) throws NameNotFoundException { } }

implementation: addIntentFilterForComponent ( componentName , filter , serviceFilters ) ;


signature:
public class ShadowPackageManager { /** * Add intent filter for given receiver .
 * @ throws NameNotFoundException if component with given name doesn ' t exist . */
public void addIntentFilterForReceiver ( ComponentName componentName , IntentFilter filter ) throws NameNotFoundException { } }

implementation: addIntentFilterForComponent ( componentName , filter , receiverFilters ) ;


signature:
public class ShadowPackageManager { /** * Add intent filter for given provider .
 * @ throws NameNotFoundException if component with given name doesn ' t exist . */
public void addIntentFilterForProvider ( ComponentName componentName , IntentFilter filter ) throws NameNotFoundException { } }

implementation: addIntentFilterForComponent ( componentName , filter , providerFilters ) ;


signature:
public class ShadowPackageManager { /** * Method to retrieve persistent preferred activities as set by { @ link
 * android . app . admin . DevicePolicyManager # addPersistentPreferredActivity } .
 * Works the same way as analogous { @ link PackageManager # getPreferredActivities } for regular
 * preferred activities . */
public int getPersistentPreferredActivities ( List < IntentFilter > outFilters , List < ComponentName > outActivities , String packageName ) { } }

implementation: return getPreferredActivitiesInternal ( outFilters , outActivities , packageName , persistentPreferredActivities ) ;


signature:
public class ShadowPackageManager { /** * Returns the current { @ link PackageSetting } of { @ code packageName } .
 * If { @ code packageName } is not present in this { @ link ShadowPackageManager } , this method will
 * return null . */
public PackageSetting getPackageSetting ( String packageName ) { } }

implementation: PackageSetting setting = packageSettings . get ( packageName ) ; return setting == null ? null : new PackageSetting ( setting ) ;


signature:
public class ShadowSharedMemory { /** * Only works on { @ link SharedMemory } instances from { @ link SharedMemory # create } .
 * < p > " prot " is ignored - - all mappings are read / write . */
@ Implementation protected ByteBuffer map ( int prot , int offset , int length ) throws ErrnoException { } }

implementation:
ReflectionHelpers . callInstanceMethod ( realObject , "checkOpen" ) ; File file = filesByFd . get ( getRealFileDescriptor ( ) ) ; if ( file == null ) { throw new IllegalStateException ( "SharedMemory from a parcel isn't yet implemented!" ) ; } try ( RandomAccessFile randomAccessFile = new RandomAccessFile ( file , "rw" ) ) { // It would be easy to support a MapMode . READ _ ONLY type mapping as well except none of the
// OsConstants fields are even initialized by robolectric and so " prot " is always zero !
return randomAccessFile . getChannel ( ) . map ( MapMode . READ_WRITE , offset , length ) ; } catch ( IOException e ) { throw new ErrnoException ( e . getMessage ( ) , OsConstants . EIO , e ) ; }


signature:
public class LocaleData { /** * to represent the root locale */
private static int findParent ( int packed_locale , final String script ) { } }

implementation: if ( hasRegion ( packed_locale ) ) { for ( Map . Entry < String , Map < Integer , Integer > > entry : SCRIPT_PARENTS . entrySet ( ) ) { if ( script . equals ( entry . getKey ( ) ) ) { Map < Integer , Integer > map = entry . getValue ( ) ; Integer lookup_result = map . get ( packed_locale ) ; if ( lookup_result != null ) { return lookup_result ; } break ; } } return dropRegion ( packed_locale ) ; } return PACKED_ROOT ;


signature:
public class LocaleData { /** * any results in ' out ' . ) */
static int findAncestors ( int [ ] out , Ref < Long > stop_list_index , int packed_locale , final String script , final int [ ] stop_list , int stop_set_length ) { } }

implementation: int ancestor = packed_locale ; int count = 0 ; do { if ( out != null ) { out [ count ] = ancestor ; } count ++ ; for ( int i = 0 ; i < stop_set_length ; i ++ ) { if ( stop_list [ i ] == ancestor ) { stop_list_index . set ( ( long ) i ) ; return count ; } } ancestor = findParent ( ancestor , script ) ; } while ( ancestor != PACKED_ROOT ) ; stop_list_index . set ( ( long ) - 1 ) ; return count ;


signature:
public class LocalDependencyResolver { /** * Validates { @ code file } is an existing file that is readable .
 * @ param file the File to test
 * @ return the provided file , if all validation passes
 * @ throws IllegalArgumentException if validation fails */
private static File validateFile ( File file ) throws IllegalArgumentException { } }

implementation: if ( ! file . isFile ( ) ) { throw new IllegalArgumentException ( "Path is not a file: " + file ) ; } if ( ! file . canRead ( ) ) { throw new IllegalArgumentException ( "Unable to read file: " + file ) ; } return file ;


signature:
public class ShadowCameraCharacteristics { /** * Sets the value for a given key .
 * @ throws IllegalArgumentException if there ' s an existing value for the key . */
public < T > void set ( Key < T > key , Object value ) { } }

implementation: Preconditions . checkArgument ( ! charactersKeyToValue . containsKey ( key ) ) ; charactersKeyToValue . put ( key , value ) ;


signature:
public class OldClassInstrumentor { /** * Generates code like this :
 * ` ` ` java
 * public ThisClass ( DirectObjectMarker dom , ThisClass domInstance ) {
 * super ( dom , domInstance ) ;
 * _ _ robo _ data _ _ = domInstance ; */
@ Override protected void addDirectCallConstructor ( MutableClass mutableClass ) { } }

implementation: MethodNode directCallConstructor = new MethodNode ( Opcodes . ACC_PUBLIC , "<init>" , "(" + DIRECT_OBJECT_MARKER_TYPE_DESC + mutableClass . classType . getDescriptor ( ) + ")V" , null , null ) ; RobolectricGeneratorAdapter generator = new RobolectricGeneratorAdapter ( directCallConstructor ) ; generator . loadThis ( ) ; String superName = mutableClass . classNode . superName ; if ( superName . equals ( "java/lang/Object" ) ) { generator . visitMethodInsn ( Opcodes . INVOKESPECIAL , superName , "<init>" , "()V" , false ) ; } else { generator . loadArgs ( ) ; generator . visitMethodInsn ( Opcodes . INVOKESPECIAL , superName , "<init>" , "(" + DIRECT_OBJECT_MARKER_TYPE_DESC + "L" + superName + ";)V" , false ) ; } generator . loadThis ( ) ; generator . loadArg ( 1 ) ; generator . putField ( mutableClass . classType , ShadowConstants . CLASS_HANDLER_DATA_FIELD_NAME , OBJECT_TYPE ) ; generator . returnValue ( ) ; mutableClass . addMethod ( directCallConstructor ) ;


signature:
public class OldClassInstrumentor { /** * Generates codelike this :
 * ` ` ` java
 * / / decorator - specific code . . .
 * Plan plan = RobolectricInternals . methodInvoked (
 * " pkg / ThisClass / thisMethod ( Ljava / lang / String ; Z ) V " , isStatic , ThisClass . class ) ;
 * if ( plan ! = null ) {
 * try {
 * return plan . run ( this , args ) ;
 * } catch ( Throwable t ) {
 * throw RobolectricInternals . cleanStackTrace ( t ) ;
 * } else {
 * return $ $ robo $ $ thisMethod ( * args ) ; */
private void generateCallToClassHandler ( MutableClass mutableClass , MethodNode originalMethod , String originalMethodName , RobolectricGeneratorAdapter generator ) { } }

implementation:
decorator . decorateMethodPreClassHandler ( mutableClass , originalMethod , originalMethodName , generator ) ; int planLocalVar = generator . newLocal ( PLAN_TYPE ) ; int exceptionLocalVar = generator . newLocal ( THROWABLE_TYPE ) ; Label directCall = new Label ( ) ; Label doReturn = new Label ( ) ; // prepare for call to classHandler . methodInvoked ( String signature , boolean isStatic )
generator . push ( mutableClass . classType . getInternalName ( ) + "/" + originalMethodName + originalMethod . desc ) ; generator . push ( generator . isStatic ( ) ) ; generator . push ( mutableClass . classType ) ; // my class
generator . invokeStatic ( ROBOLECTRIC_INTERNALS_TYPE , METHOD_INVOKED_METHOD ) ; generator . storeLocal ( planLocalVar ) ; generator . loadLocal ( planLocalVar ) ; // plan
generator . ifNull ( directCall ) ; // prepare for call to plan . run ( Object instance , Object [ ] params )
TryCatch tryCatchForHandler = generator . tryStart ( THROWABLE_TYPE ) ; generator . loadLocal ( planLocalVar ) ; // plan
generator . loadThisOrNull ( ) ; // instance
generator . loadArgArray ( ) ; // params
generator . invokeInterface ( PLAN_TYPE , PLAN_RUN_METHOD ) ; Type returnType = generator . getReturnType ( ) ; int sort = returnType . getSort ( ) ; switch ( sort ) { case VOID : generator . pop ( ) ; break ; case OBJECT : /* falls through */
case ARRAY : generator . checkCast ( returnType ) ; break ; default : int unboxLocalVar = generator . newLocal ( OBJECT_TYPE ) ; generator . storeLocal ( unboxLocalVar ) ; generator . loadLocal ( unboxLocalVar ) ; Label notNull = generator . newLabel ( ) ; Label afterward = generator . newLabel ( ) ; generator . ifNonNull ( notNull ) ; generator . pushDefaultReturnValueToStack ( returnType ) ; // return zero , false , whatever
generator . goTo ( afterward ) ; generator . mark ( notNull ) ; generator . loadLocal ( unboxLocalVar ) ; generator . unbox ( returnType ) ; generator . mark ( afterward ) ; break ; } tryCatchForHandler . end ( ) ; generator . goTo ( doReturn ) ; // catch ( Throwable )
tryCatchForHandler . handler ( ) ; generator . storeLocal ( exceptionLocalVar ) ; generator . loadLocal ( exceptionLocalVar ) ; generator . invokeStatic ( ROBOLECTRIC_INTERNALS_TYPE , HANDLE_EXCEPTION_METHOD ) ; generator . throwException ( ) ; if ( ! originalMethod . name . equals ( "<init>" ) ) { generator . mark ( directCall ) ; TryCatch tryCatchForDirect = generator . tryStart ( THROWABLE_TYPE ) ; generator . invokeMethod ( mutableClass . classType . getInternalName ( ) , originalMethod . name , originalMethod . desc ) ; tryCatchForDirect . end ( ) ; generator . returnValue ( ) ; // catch ( Throwable )
tryCatchForDirect . handler ( ) ; generator . storeLocal ( exceptionLocalVar ) ; generator . loadLocal ( exceptionLocalVar ) ; generator . invokeStatic ( ROBOLECTRIC_INTERNALS_TYPE , HANDLE_EXCEPTION_METHOD ) ; generator . throwException ( ) ; } generator . mark ( doReturn ) ; generator . returnValue ( ) ;


signature:
public class OldClassInstrumentor { /** * Intercepts the method without using the invokedynamic bytecode instruction .
 * Should be called through interceptInvokeVirtualMethod , not directly . */
private void interceptInvokeVirtualMethodWithoutInvokeDynamic ( MutableClass mutableClass , ListIterator < AbstractInsnNode > instructions , MethodInsnNode targetMethod ) { } }

implementation:
boolean isStatic = targetMethod . getOpcode ( ) == Opcodes . INVOKESTATIC ; instructions . remove ( ) ; // remove the method invocation
Type [ ] argumentTypes = Type . getArgumentTypes ( targetMethod . desc ) ; instructions . add ( new LdcInsnNode ( argumentTypes . length ) ) ; instructions . add ( new TypeInsnNode ( Opcodes . ANEWARRAY , "java/lang/Object" ) ) ; // first , move any arguments into an Object [ ] in reverse order
for ( int i = argumentTypes . length - 1 ; i >= 0 ; i -- ) { Type type = argumentTypes [ i ] ; int argWidth = type . getSize ( ) ; if ( argWidth == 1 ) { // A B C [ ]
instructions . add ( new InsnNode ( Opcodes . DUP_X1 ) ) ; // A B [ ] C [ ]
instructions . add ( new InsnNode ( Opcodes . SWAP ) ) ; // A B [ ] [ ] C
instructions . add ( new LdcInsnNode ( i ) ) ; // A B [ ] [ ] C 2
instructions . add ( new InsnNode ( Opcodes . SWAP ) ) ; // A B [ ] [ ] 2 C
box ( type , instructions ) ; // A B [ ] [ ] 2 ( C )
instructions . add ( new InsnNode ( Opcodes . AASTORE ) ) ; // A B [ ( C ) ]
} else if ( argWidth == 2 ) { // A B _ C _ [ ]
instructions . add ( new InsnNode ( Opcodes . DUP_X2 ) ) ; // A B [ ] _ C _ [ ]
instructions . add ( new InsnNode ( Opcodes . DUP_X2 ) ) ; // A B [ ] [ ] _ C _ [ ]
instructions . add ( new InsnNode ( Opcodes . POP ) ) ; // A B [ ] [ ] _ C _
box ( type , instructions ) ; // A B [ ] [ ] ( C )
instructions . add ( new LdcInsnNode ( i ) ) ; // A B [ ] [ ] ( C ) 2
instructions . add ( new InsnNode ( Opcodes . SWAP ) ) ; // A B [ ] [ ] 2 ( C )
instructions . add ( new InsnNode ( Opcodes . AASTORE ) ) ; // A B [ ( C ) ]
} } if ( isStatic ) { instructions . add ( new InsnNode ( Opcodes . ACONST_NULL ) ) ; // [ ] null
instructions . add ( new InsnNode ( Opcodes . SWAP ) ) ; // null [ ]
} // instance [ ]
instructions . add ( new LdcInsnNode ( targetMethod . owner + "/" + targetMethod . name + targetMethod . desc ) ) ; // target method signature
// instance [ ] signature
instructions . add ( new InsnNode ( Opcodes . DUP_X2 ) ) ; // signature instance [ ] signature
instructions . add ( new InsnNode ( Opcodes . POP ) ) ; // signature instance [ ]
instructions . add ( new LdcInsnNode ( mutableClass . classType ) ) ; // signature instance [ ] class
instructions . add ( new MethodInsnNode ( Opcodes . INVOKESTATIC , Type . getType ( RobolectricInternals . class ) . getInternalName ( ) , "intercept" , "(Ljava/lang/String;Ljava/lang/Object;[Ljava/lang/Object;Ljava/lang/Class;)Ljava/lang/Object;" , false ) ) ; final Type returnType = Type . getReturnType ( targetMethod . desc ) ; switch ( returnType . getSort ( ) ) { case ARRAY : /* falls through */
case OBJECT : String remappedType = mutableClass . config . mappedTypeName ( returnType . getInternalName ( ) ) ; instructions . add ( new TypeInsnNode ( Opcodes . CHECKCAST , remappedType ) ) ; break ; case VOID : instructions . add ( new InsnNode ( Opcodes . POP ) ) ; break ; case Type . LONG : instructions . add ( new TypeInsnNode ( Opcodes . CHECKCAST , Type . getInternalName ( Long . class ) ) ) ; instructions . add ( new MethodInsnNode ( Opcodes . INVOKEVIRTUAL , Type . getInternalName ( Long . class ) , "longValue" , Type . getMethodDescriptor ( Type . LONG_TYPE ) , false ) ) ; break ; case Type . FLOAT : instructions . add ( new TypeInsnNode ( Opcodes . CHECKCAST , Type . getInternalName ( Float . class ) ) ) ; instructions . add ( new MethodInsnNode ( Opcodes . INVOKEVIRTUAL , Type . getInternalName ( Float . class ) , "floatValue" , Type . getMethodDescriptor ( Type . FLOAT_TYPE ) , false ) ) ; break ; case Type . DOUBLE : instructions . add ( new TypeInsnNode ( Opcodes . CHECKCAST , Type . getInternalName ( Double . class ) ) ) ; instructions . add ( new MethodInsnNode ( Opcodes . INVOKEVIRTUAL , Type . getInternalName ( Double . class ) , "doubleValue" , Type . getMethodDescriptor ( Type . DOUBLE_TYPE ) , false ) ) ; break ; case Type . BOOLEAN : instructions . add ( new TypeInsnNode ( Opcodes . CHECKCAST , Type . getInternalName ( Boolean . class ) ) ) ; instructions . add ( new MethodInsnNode ( Opcodes . INVOKEVIRTUAL , Type . getInternalName ( Boolean . class ) , "booleanValue" , Type . getMethodDescriptor ( Type . BOOLEAN_TYPE ) , false ) ) ; break ; case Type . INT : instructions . add ( new TypeInsnNode ( Opcodes . CHECKCAST , Type . getInternalName ( Integer . class ) ) ) ; instructions . add ( new MethodInsnNode ( Opcodes . INVOKEVIRTUAL , Type . getInternalName ( Integer . class ) , "intValue" , Type . getMethodDescriptor ( Type . INT_TYPE ) , false ) ) ; break ; case Type . SHORT : instructions . add ( new TypeInsnNode ( Opcodes . CHECKCAST , Type . getInternalName ( Short . class ) ) ) ; instructions . add ( new MethodInsnNode ( Opcodes . INVOKEVIRTUAL , Type . getInternalName ( Short . class ) , "shortValue" , Type . getMethodDescriptor ( Type . SHORT_TYPE ) , false ) ) ; break ; case Type . BYTE : instructions . add ( new TypeInsnNode ( Opcodes . CHECKCAST , Type . getInternalName ( Byte . class ) ) ) ; instructions . add ( new MethodInsnNode ( Opcodes . INVOKEVIRTUAL , Type . getInternalName ( Byte . class ) , "byteValue" , Type . getMethodDescriptor ( Type . BYTE_TYPE ) , false ) ) ; break ; default : throw new RuntimeException ( "Not implemented: " + getClass ( ) . getName ( ) + " cannot intercept methods with return type " + returnType . getClassName ( ) ) ; }


signature:
public class ShadowNetworkInfo { /** * Allows developers to create a { @ link NetworkInfo } instance for testing . */
public static NetworkInfo newInstance ( NetworkInfo . DetailedState detailedState , int type , int subType , boolean isAvailable , NetworkInfo . State state ) { } }

implementation: NetworkInfo networkInfo = Shadow . newInstanceOf ( NetworkInfo . class ) ; final ShadowNetworkInfo info = Shadow . extract ( networkInfo ) ; info . setConnectionType ( type ) ; info . setSubType ( subType ) ; info . setDetailedState ( detailedState ) ; info . setAvailableStatus ( isAvailable ) ; info . setConnectionStatus ( state ) ; return networkInfo ;


signature:
public class ShadowNetworkInfo { /** * Sets up the return value of { @ link # isConnectedOrConnecting ( ) } , { @ link # isConnected ( ) } , and
 * { @ link # getState ( ) } . If the input is true , state will be { @ link NetworkInfo . State # CONNECTED } ,
 * else it will be { @ link NetworkInfo . State # DISCONNECTED } .
 * @ param isConnected the value that { @ link # isConnectedOrConnecting ( ) } and { @ link # isConnected ( ) }
 * will return .
 * @ deprecated use { @ link # setConnectionStatus ( NetworkInfo . State ) } instead */
@ Deprecated public void setConnectionStatus ( boolean isConnected ) { } }

implementation: setConnectionStatus ( isConnected ? NetworkInfo . State . CONNECTED : NetworkInfo . State . DISCONNECTED ) ;


signature:
public class ShadowPackageParser { /** * Parses an AndroidManifest . xml file using the framework PackageParser . */
public static Package callParsePackage ( Path apkFile ) { } }

implementation:
PackageParser packageParser = new PackageParser ( ) ; int flags = PackageParser . PARSE_IGNORE_PROCESSES ; try { Package thePackage ; if ( RuntimeEnvironment . getApiLevel ( ) >= Build . VERSION_CODES . LOLLIPOP ) { // TODO ( christianw / brettchabot ) : workaround for NPE from probable bug in Q .
// Can be removed when upstream properly handles a null callback
// PackageParser # setMinAspectRatio ( Package )
if ( RuntimeEnvironment . getApiLevel ( ) >= Build . VERSION_CODES . Q ) { QHelper . setCallback ( packageParser ) ; } thePackage = packageParser . parsePackage ( apkFile . toFile ( ) , flags ) ; } else { // JB - > KK
thePackage = reflector ( _PackageParser_ . class , packageParser ) . parsePackage ( apkFile . toFile ( ) , Fs . externalize ( apkFile ) , new DisplayMetrics ( ) , flags ) ; } if ( thePackage == null ) { List < LogItem > logItems = ShadowLog . getLogsForTag ( "PackageParser" ) ; if ( logItems . isEmpty ( ) ) { throw new RuntimeException ( "Failed to parse package " + apkFile ) ; } else { LogItem logItem = logItems . get ( 0 ) ; throw new RuntimeException ( "Failed to parse package " + apkFile + ": " + logItem . msg , logItem . throwable ) ; } } return thePackage ; } catch ( Exception e ) { throw new RuntimeException ( e ) ; }


signature:
public class LocalActivityInvoker { /** * This implementation makes sure , that the activity you are trying to launch exists */
@ Override public Intent getIntentForActivity ( Class < ? extends Activity > activityClass ) { } }

implementation: PackageManager packageManager = getTargetContext ( ) . getPackageManager ( ) ; ComponentName componentName = new ComponentName ( getTargetContext ( ) , activityClass ) ; Intent intent = Intent . makeMainActivity ( componentName ) ; if ( packageManager . resolveActivity ( intent , 0 ) != null ) { return intent ; } return Intent . makeMainActivity ( new ComponentName ( getContext ( ) , activityClass ) ) ;


signature:
public class LoadedArsc { /** * the ResChunk _ header is safe . */
static boolean VerifyResTableType ( ResTable_type header ) { } }

implementation:
if ( header . id == 0 ) { logError ( "RES_TABLE_TYPE_TYPE has invalid ID 0." ) ; return false ; } int entry_count = dtohl ( header . entryCount ) ; // if ( entry _ count > std . numeric _ limits < uint16 _ t > . max ( ) ) {
if ( entry_count > 0xffff ) { logError ( "RES_TABLE_TYPE_TYPE has too many entries (" + entry_count + ")." ) ; return false ; } // Make sure that there is enough room for the entry offsets .
int offsets_offset = dtohs ( header . header . headerSize ) ; int entries_offset = dtohl ( header . entriesStart ) ; int offsets_length = 4 * entry_count ; if ( offsets_offset > entries_offset || entries_offset - offsets_offset < offsets_length ) { logError ( "RES_TABLE_TYPE_TYPE entry offsets overlap actual entry data." ) ; return false ; } if ( entries_offset > dtohl ( header . header . size ) ) { logError ( "RES_TABLE_TYPE_TYPE entry offsets extend beyond chunk." ) ; return false ; } if ( isTruthy ( entries_offset & 0x03 ) ) { logError ( "RES_TABLE_TYPE_TYPE entries start at unaligned address." ) ; return false ; } return true ;


signature:
public class LoadedArsc { /** * exists . */
LoadedPackage GetPackageById ( int package_id ) { } }

implementation: for ( LoadedPackage loaded_package : packages_ ) { if ( loaded_package . GetPackageId ( ) == package_id ) { return loaded_package ; } } return null ;


signature:
public class LoadedArsc { /** * ID . */
static LoadedArsc Load ( StringPiece data , LoadedIdmap loaded_idmap /* = null */
, boolean system /* = false */
, boolean load_as_shared_library /* = false */
) { } }

implementation:
// ATRACE _ NAME ( " LoadedArsc : : LoadTable " ) ;
// Not using make _ unique because the constructor is private .
LoadedArsc loaded_arsc = new LoadedArsc ( ) ; loaded_arsc . system_ = system ; Chunk . Iterator iter = new Iterator ( data , data . size ( ) ) ; while ( iter . HasNext ( ) ) { Chunk chunk = iter . Next ( ) ; switch ( chunk . type ( ) ) { case RES_TABLE_TYPE : if ( ! loaded_arsc . LoadTable ( chunk , loaded_idmap , load_as_shared_library ) ) { return emptyBraces ( ) ; } break ; default : logWarning ( String . format ( "Unknown chunk type '%02x'." , chunk . type ( ) ) ) ; break ; } } if ( iter . HadError ( ) ) { logError ( iter . GetLastError ( ) ) ; if ( iter . HadFatalError ( ) ) { return emptyBraces ( ) ; } } // Need to force a move for mingw32.
// return std . move ( loaded _ arsc ) ;
return loaded_arsc ;


signature:
public class ShadowPath { /** * Returns the Java2D winding rules matching a given Android { @ link FillType } .
 * @ param type the android fill type
 * @ return the matching java2d winding rule . */
private static int getWindingRule ( Path . FillType type ) { } }

implementation: switch ( type ) { case WINDING : case INVERSE_WINDING : return GeneralPath . WIND_NON_ZERO ; case EVEN_ODD : case INVERSE_EVEN_ODD : return GeneralPath . WIND_EVEN_ODD ; default : assert false ; return GeneralPath . WIND_NON_ZERO ; }


signature:
public class ShadowPath { /** * Fills the given { @ link RectF } with the path bounds .
 * @ param bounds the RectF to be filled . */
public void fillBounds ( RectF bounds ) { } }

implementation: Rectangle2D rect = mPath . getBounds2D ( ) ; bounds . left = ( float ) rect . getMinX ( ) ; bounds . right = ( float ) rect . getMaxX ( ) ; bounds . top = ( float ) rect . getMinY ( ) ; bounds . bottom = ( float ) rect . getMaxY ( ) ;


signature:
public class ShadowWifiManager { /** * Adds or updates a network which can later be retrieved with { @ link # getWifiConfiguration ( int ) }
 * method . A null { @ param config } , or one with a networkId less than 0 , or a networkId that had
 * its updatePermission removed using the { @ link # setUpdateNetworkPermission ( int , boolean ) } will
 * return - 1 , which indicates a failure to update . */
@ Implementation protected int updateNetwork ( WifiConfiguration config ) { } }

implementation: if ( config == null || config . networkId < 0 || readOnlyNetworkIds . get ( config . networkId ) ) { return - 1 ; } networkIdToConfiguredNetworks . put ( config . networkId , makeCopy ( config , config . networkId ) ) ; return config . networkId ;


signature:
public class CppApkAssets { /** * std : : unique _ ptr < const ApkAssets > ApkAssets : : Load ( const String & path , bool system ) { */
public static CppApkAssets Load ( String path , boolean system ) { } }

implementation:
return LoadImpl ( - 1 /* fd */
, path , null , null , system , false /* load _ as _ shared _ library */
) ;


signature:
public class CppApkAssets { /** * bool system ) { */
public static CppApkAssets LoadAsSharedLibrary ( String path , boolean system ) { } }

implementation:
return LoadImpl ( - 1 /* fd */
, path , null , null , system , true /* load _ as _ shared _ library */
) ;


signature:
public class CppApkAssets { /** * Measure performance implications of loading { @ link CppApkAssets } . */
static CppApkAssets LoadImpl ( int fd , String path , Asset idmap_asset , LoadedIdmap loaded_idmap , boolean system , boolean load_as_shared_library ) { } }

implementation: return PerfStatsCollector . getInstance ( ) . measure ( "load binary " + ( system ? "framework" : "app" ) + " resources" , ( ) -> LoadImpl_measured ( fd , path , idmap_asset , loaded_idmap , system , load_as_shared_library ) ) ;


signature:
public class CppApkAssets { /** * std : : unique _ ptr < const LoadedIdmap > loaded _ idmap , bool system , bool load _ as _ shared _ library ) { */
static CppApkAssets LoadImpl_measured ( int fd , String path , Asset idmap_asset , LoadedIdmap loaded_idmap , boolean system , boolean load_as_shared_library ) { } }

implementation:
Ref < ZipArchiveHandle > unmanaged_handle = new Ref < > ( null ) ; int result ; if ( fd >= 0 ) { throw new UnsupportedOperationException ( ) ; // result =
// OpenArchiveFd ( fd . release ( ) , path , & unmanaged _ handle , true / * assume _ ownership * / ) ;
} else { result = OpenArchive ( path , unmanaged_handle ) ; } if ( result != 0 ) { System . err . println ( "Failed to open APK '" + path + "' " + ErrorCodeString ( result ) ) ; return null ; } // Wrap the handle in a unique _ ptr so it gets automatically closed .
CppApkAssets loaded_apk = new CppApkAssets ( unmanaged_handle . get ( ) , path ) ; // Find the resource table .
String entry_name = kResourcesArsc ; Ref < ZipEntry > entry = new Ref < > ( null ) ; // result = FindEntry ( loaded _ apk . zip _ handle _ . get ( ) , entry _ name , & entry ) ;
result = ZipFileRO . FindEntry ( loaded_apk . zip_handle_ , entry_name , entry ) ; if ( result != 0 ) { // There is no resources . arsc , so create an empty LoadedArsc and return .
loaded_apk . loaded_arsc_ = LoadedArsc . CreateEmpty ( ) ; return loaded_apk ; } if ( entry . get ( ) . getMethod ( ) == kCompressDeflated ) { System . out . println ( kResourcesArsc + " in APK '" + path + "' is compressed." ) ; } // Open the resource table via mmap unless it is compressed . This logic is taken care of by Open .
loaded_apk . resources_asset_ = loaded_apk . Open ( kResourcesArsc , Asset . AccessMode . ACCESS_BUFFER ) ; if ( loaded_apk . resources_asset_ == null ) { System . err . println ( "Failed to open '" + kResourcesArsc + "' in APK '" + path + "'." ) ; return null ; } // Must retain ownership of the IDMAP Asset so that all pointers to its mmapped data remain valid .
loaded_apk . idmap_asset_ = idmap_asset ; // const StringPiece data (
// reinterpret _ cast < const char * > ( loaded _ apk . resources _ asset _ . getBuffer ( true / * wordAligned * / ) ) ,
// loaded _ apk . resources _ asset _ . getLength ( ) ) ;
StringPiece data = new StringPiece ( ByteBuffer . wrap ( loaded_apk . resources_asset_ . getBuffer ( true /* wordAligned */
) ) . order ( ByteOrder . LITTLE_ENDIAN ) , 0 /* ( int ) loaded _ apk . resources _ asset _ . getLength ( ) */
) ; loaded_apk . loaded_arsc_ = LoadedArsc . Load ( data , loaded_idmap , system , load_as_shared_library ) ; if ( loaded_apk . loaded_arsc_ == null ) { System . err . println ( "Failed to load '" + kResourcesArsc + "' in APK '" + path + "'." ) ; return null ; } // Need to force a move for mingw32.
return loaded_apk ;


signature:
public class MavenManifestFactory { /** * Find valid library AndroidManifest files referenced from an already loaded AndroidManifest ' s
 * ` project . properties ` file , recursively . */
private static List < ManifestIdentifier > findLibraries ( Path resDirectory ) throws IOException { } }

implementation:
List < ManifestIdentifier > libraryBaseDirs = new ArrayList < > ( ) ; if ( resDirectory != null ) { Path baseDir = resDirectory . getParent ( ) ; final Properties properties = getProperties ( baseDir . resolve ( "project.properties" ) ) ; Properties overrideProperties = getProperties ( baseDir . resolve ( "test-project.properties" ) ) ; properties . putAll ( overrideProperties ) ; int libRef = 1 ; String lib ; while ( ( lib = properties . getProperty ( "android.library.reference." + libRef ) ) != null ) { Path libraryDir = baseDir . resolve ( lib ) ; if ( Files . isDirectory ( libraryDir ) ) { // Ignore directories without any files
Path [ ] libraryBaseDirFiles = Fs . listFiles ( libraryDir ) ; if ( libraryBaseDirFiles != null && libraryBaseDirFiles . length > 0 ) { List < ManifestIdentifier > libraries = findLibraries ( libraryDir . resolve ( Config . DEFAULT_RES_FOLDER ) ) ; libraryBaseDirs . add ( new ManifestIdentifier ( null , libraryDir . resolve ( Config . DEFAULT_MANIFEST_NAME ) , libraryDir . resolve ( Config . DEFAULT_RES_FOLDER ) , libraryDir . resolve ( Config . DEFAULT_ASSET_FOLDER ) , libraries ) ) ; } } libRef ++ ; } } return libraryBaseDirs ;


signature:
public class ShadowDevicePolicyManager { /** * Set package names for witch { @ link DevicePolicyManager # setApplicationHidden } should fail .
 * @ param packagesToFail collection of package names or { @ code null } to clear the packages . */
public void failSetApplicationHiddenFor ( Collection < String > packagesToFail ) { } }

implementation: if ( packagesToFail == null ) { packagesToFail = Collections . emptySet ( ) ; } packagesToFailForSetApplicationHidden = packagesToFail ;


signature:
public class ShadowDevicePolicyManager { /** * Returns all application restrictions of the { @ code packageName } in a { @ link Bundle } . */
public Bundle getApplicationRestrictions ( String packageName ) { } }

implementation:
Bundle bundle = applicationRestrictionsMap . get ( packageName ) ; // If no restrictions were saved , DPM method should return an empty Bundle as per JavaDoc .
return bundle != null ? new Bundle ( bundle ) : new Bundle ( ) ;


signature:
public class ShadowDevicePolicyManager { /** * Sets the application restrictions of the { @ code packageName } .
 * < p > The new { @ code applicationRestrictions } always completely overwrites any existing ones . */
public void setApplicationRestrictions ( String packageName , Bundle applicationRestrictions ) { } }

implementation: applicationRestrictionsMap . put ( packageName , new Bundle ( applicationRestrictions ) ) ;


signature:
public class ShadowDevicePolicyManager { /** * Sets organization name .
 * < p > The API can only be called by profile owner since Android N and can be called by both of
 * profile owner and device owner since Android O . */
@ Implementation ( minSdk = N ) protected void setOrganizationName ( ComponentName admin , @ Nullable CharSequence name ) { } }

implementation: if ( Build . VERSION . SDK_INT >= Build . VERSION_CODES . O ) { enforceDeviceOwnerOrProfileOwner ( admin ) ; } else { enforceProfileOwner ( admin ) ; } if ( TextUtils . isEmpty ( name ) ) { organizationName = null ; } else { organizationName = name ; }


signature:
public class ShadowDevicePolicyManager { /** * Returns organization name .
 * < p > The API can only be called by profile owner since Android N .
 * < p > Android framework has a hidden API for getting the organization name for device owner since
 * Android O . This method , however , is extended to return the organization name for device owners
 * too to make testing of { @ link # setOrganizationName ( ComponentName , CharSequence ) } easier for
 * device owner cases . */
@ Implementation ( minSdk = N ) @ Nullable protected CharSequence getOrganizationName ( ComponentName admin ) { } }

implementation: if ( Build . VERSION . SDK_INT >= Build . VERSION_CODES . O ) { enforceDeviceOwnerOrProfileOwner ( admin ) ; } else { enforceProfileOwner ( admin ) ; } return organizationName ;


signature:
public class ShadowDevicePolicyManager { /** * Sets permitted accessibility services .
 * < p > The API can be called by either a profile or device owner .
 * < p > This method does not check already enabled non - system accessibility services , so will always
 * set the restriction and return true . */
@ Implementation ( minSdk = LOLLIPOP ) protected boolean setPermittedAccessibilityServices ( ComponentName admin , List < String > packageNames ) { } }

implementation: enforceDeviceOwnerOrProfileOwner ( admin ) ; permittedAccessibilityServices = packageNames ; return true ;


signature:
public class ShadowDevicePolicyManager { /** * Sets permitted input methods .
 * < p > The API can be called by either a profile or device owner .
 * < p > This method does not check already enabled non - system input methods , so will always set the
 * restriction and return true . */
@ Implementation ( minSdk = LOLLIPOP ) protected boolean setPermittedInputMethods ( ComponentName admin , List < String > packageNames ) { } }

implementation: enforceDeviceOwnerOrProfileOwner ( admin ) ; permittedInputMethods = packageNames ; return true ;


signature:
public class ShadowDevicePolicyManager { /** * Setter for { @ link DevicePolicyManager # getStorageEncryptionStatus ( ) } . */
public void setStorageEncryptionStatus ( int status ) { } }

implementation: switch ( status ) { case DevicePolicyManager . ENCRYPTION_STATUS_ACTIVE : case DevicePolicyManager . ENCRYPTION_STATUS_INACTIVE : case DevicePolicyManager . ENCRYPTION_STATUS_ACTIVATING : case DevicePolicyManager . ENCRYPTION_STATUS_UNSUPPORTED : break ; case DevicePolicyManager . ENCRYPTION_STATUS_ACTIVE_DEFAULT_KEY : if ( RuntimeEnvironment . getApiLevel ( ) < M ) { throw new IllegalArgumentException ( "status " + status + " requires API " + M ) ; } break ; case DevicePolicyManager . ENCRYPTION_STATUS_ACTIVE_PER_USER : if ( RuntimeEnvironment . getApiLevel ( ) < N ) { throw new IllegalArgumentException ( "status " + status + " requires API " + N ) ; } break ; default : throw new IllegalArgumentException ( "Unknown status: " + status ) ; } storageEncryptionStatus = status ;


signature:
public class ShadowDevicePolicyManager { /** * Activates reset token for given admin .
 * @ param admin Which { @ link DeviceAdminReceiver } this request is associated with .
 * @ return if the activation state changed .
 * @ throws IllegalArgumentException if there is no token set for this admin . */
public boolean activateResetToken ( ComponentName admin ) { } }

implementation: if ( ! passwordResetTokens . containsKey ( admin ) ) { throw new IllegalArgumentException ( "No token set for comopnent: " + admin ) ; } return componentsWithActivatedTokens . add ( admin ) ;


signature:
public class ShadowDevicePolicyManager { /** * Grants a particular device policy for an active ComponentName .
 * @ param admin the ComponentName which DeviceAdminReceiver this request is associated with . Must
 * be an active administrator , or an exception will be thrown . This value must never be null .
 * @ param usesPolicy the uses - policy to check */
public void grantPolicy ( @ NonNull ComponentName admin , int usesPolicy ) { } }

implementation: enforceActiveAdmin ( admin ) ; Set < Integer > policyGrantedSet = adminPolicyGrantedMap . get ( admin ) ; if ( policyGrantedSet == null ) { policyGrantedSet = new HashSet < > ( ) ; policyGrantedSet . add ( usesPolicy ) ; adminPolicyGrantedMap . put ( admin , policyGrantedSet ) ; } else { policyGrantedSet . add ( usesPolicy ) ; }


signature:
public class ShadowNfcAdapter { /** * Mocks setting NDEF push message so that it could be verified in the test . Use { @ link
 * # getNdefPushMessage ( ) } to verify that message was set . */
@ Implementation protected void setNdefPushMessage ( NdefMessage message , Activity activity , Activity ... activities ) { } }

implementation: if ( activity == null ) { throw new NullPointerException ( "activity cannot be null" ) ; } for ( Activity a : activities ) { if ( a == null ) { throw new NullPointerException ( "activities cannot contain null" ) ; } } this . ndefPushMessage = message ; this . ndefPushMessageSet = true ;


signature:
public class ShadowNfcAdapter { /** * Sets callback that should be used on successful Android Beam ( TM ) .
 * < p > The last registered callback is recalled and can be fetched using { @ link
 * # getOnNdefPushCompleteCallback } . */
@ Implementation protected void setOnNdefPushCompleteCallback ( NfcAdapter . OnNdefPushCompleteCallback callback , Activity activity , Activity ... activities ) { } }

implementation: if ( activity == null ) { throw new NullPointerException ( "activity cannot be null" ) ; } for ( Activity a : activities ) { if ( a == null ) { throw new NullPointerException ( "activities cannot contain null" ) ; } } this . onNdefPushCompleteCallback = callback ;


signature:
public class CppAssetManager2 { /** * boolean SetApkAssets ( final List < ApkAssets > apk _ assets , boolean invalidate _ caches = true ) ; */
public boolean SetApkAssets ( final List < CppApkAssets > apk_assets , boolean invalidate_caches ) { } }

implementation:
apk_assets_ = apk_assets ; BuildDynamicRefTable ( ) ; RebuildFilterList ( ) ; if ( invalidate_caches ) { // InvalidateCaches ( static _ cast < int > ( - 1 ) ) ;
InvalidateCaches ( - 1 ) ; } return true ;


signature:
public class CppAssetManager2 { /** * void BuildDynamicRefTable ( ) ; */
void BuildDynamicRefTable ( ) { } }

implementation:
package_groups_ . clear ( ) ; // package _ ids _ . fill ( 0xff ) ;
for ( int i = 0 ; i < package_ids_ . length ; i ++ ) { package_ids_ [ i ] = ( byte ) 0xff ; } // 0x01 is reserved for the android package .
int next_package_id = 0x02 ; final int apk_assets_count = apk_assets_ . size ( ) ; for ( int i = 0 ; i < apk_assets_count ; i ++ ) { final LoadedArsc loaded_arsc = apk_assets_ . get ( i ) . GetLoadedArsc ( ) ; // for ( final std . unique _ ptr < final LoadedPackage > & package _ :
for ( final LoadedPackage package_ : loaded_arsc . GetPackages ( ) ) { // Get the package ID or assign one if a shared library .
int package_id ; if ( package_ . IsDynamic ( ) ) { package_id = next_package_id ++ ; } else { package_id = package_ . GetPackageId ( ) ; } // Add the mapping for package ID to index if not present .
byte idx = package_ids_ [ package_id ] ; if ( idx == ( byte ) 0xff ) { // package _ ids _ [ package _ id ] = idx = static _ cast < byte > ( package _ groups _ . size ( ) ) ;
package_ids_ [ package_id ] = idx = ( byte ) package_groups_ . size ( ) ; // DynamicRefTable & ref _ table = package _ groups _ . back ( ) . dynamic _ ref _ table ;
// ref _ table . mAssignedPackageId = package _ id ;
// ref _ table . mAppAsLib = package - > IsDynamic ( ) & & package - > GetPackageId ( ) = = 0x7f ;
DynamicRefTable ref_table = new DynamicRefTable ( ( byte ) package_id , package_ . IsDynamic ( ) && package_ . GetPackageId ( ) == 0x7f ) ; PackageGroup newPackageGroup = new PackageGroup ( ) ; newPackageGroup . dynamic_ref_table = ref_table ; package_groups_ . add ( newPackageGroup ) ; } PackageGroup package_group = package_groups_ . get ( idx ) ; // Add the package and to the set of packages with the same ID .
// package _ group - > packages _ . push _ back ( ConfiguredPackage { package . get ( ) , { } } ) ;
// package _ group . cookies _ . push _ back ( static _ cast < ApkAssetsCookie > ( i ) ) ;
package_group . packages_ . add ( new ConfiguredPackage ( package_ ) ) ; package_group . cookies_ . add ( ApkAssetsCookie . forInt ( i ) ) ; // Add the package name . build time ID mappings .
for ( final DynamicPackageEntry entry : package_ . GetDynamicPackageMap ( ) ) { // String package _ name ( entry . package _ name . c _ str ( ) , entry . package _ name . size ( ) ) ;
package_group . dynamic_ref_table . mEntries . put ( entry . package_name , ( byte ) entry . package_id ) ; } } } // Now assign the runtime IDs so that we have a build - time to runtime ID map .
for ( PackageGroup iter : package_groups_ ) { String package_name = iter . packages_ . get ( 0 ) . loaded_package_ . GetPackageName ( ) ; for ( PackageGroup iter2 : package_groups_ ) { iter2 . dynamic_ref_table . addMapping ( package_name , iter . dynamic_ref_table . mAssignedPackageId ) ; } }


signature:
public class CppAssetManager2 { /** * final ResStringPool GetStringPoolForCookie ( ApkAssetsCookie cookie ) const ; */
final ResStringPool GetStringPoolForCookie ( ApkAssetsCookie cookie ) { } }

implementation: if ( cookie . intValue ( ) < 0 || cookie . intValue ( ) >= apk_assets_ . size ( ) ) { return null ; } return apk_assets_ . get ( cookie . intValue ( ) ) . GetLoadedArsc ( ) . GetStringPool ( ) ;


signature:
public class CppAssetManager2 { /** * final DynamicRefTable GetDynamicRefTableForPackage ( int package _ id ) const ; */
final DynamicRefTable GetDynamicRefTableForPackage ( int package_id ) { } }

implementation: if ( package_id >= package_ids_ . length ) { return null ; } final int idx = package_ids_ [ package_id ] ; if ( idx == 0xff ) { return null ; } return package_groups_ . get ( idx ) . dynamic_ref_table ;


signature:
public class CppAssetManager2 { /** * final DynamicRefTable GetDynamicRefTableForCookie ( ApkAssetsCookie cookie ) const ; */
public final DynamicRefTable GetDynamicRefTableForCookie ( ApkAssetsCookie cookie ) { } }

implementation: for ( final PackageGroup package_group : package_groups_ ) { for ( final ApkAssetsCookie package_cookie : package_group . cookies_ ) { if ( package_cookie == cookie ) { return package_group . dynamic_ref_table ; } } } return null ;


signature:
public class CppAssetManager2 { /** * void SetConfiguration ( final ResTable _ config & configuration ) ; */
public void SetConfiguration ( final ResTable_config configuration ) { } }

implementation:
final int diff = configuration_ . diff ( configuration ) ; configuration_ = configuration ; if ( isTruthy ( diff ) ) { RebuildFilterList ( ) ; // InvalidateCaches ( static _ cast < int > ( diff ) ) ;
InvalidateCaches ( diff ) ; }


signature:
public class CppAssetManager2 { /** * boolean exclude _ mipmap = false ) ; */
public Set < ResTable_config > GetResourceConfigurations ( boolean exclude_system , boolean exclude_mipmap ) { } }

implementation:
// ATRACE _ NAME ( " AssetManager : : GetResourceConfigurations " ) ;
Set < ResTable_config > configurations = new HashSet < > ( ) ; for ( final PackageGroup package_group : package_groups_ ) { for ( final ConfiguredPackage package_ : package_group . packages_ ) { if ( exclude_system && package_ . loaded_package_ . IsSystem ( ) ) { continue ; } package_ . loaded_package_ . CollectConfigurations ( exclude_mipmap , configurations ) ; } } return configurations ;


signature:
public class CppAssetManager2 { /** * boolean merge _ equivalent _ languages = false ) ; */
public Set < String > GetResourceLocales ( boolean exclude_system , boolean merge_equivalent_languages ) { } }

implementation: ATRACE_CALL ( ) ; Set < String > locales = new HashSet < > ( ) ; for ( final PackageGroup package_group : package_groups_ ) { for ( final ConfiguredPackage package_ : package_group . packages_ ) { if ( exclude_system && package_ . loaded_package_ . IsSystem ( ) ) { continue ; } package_ . loaded_package_ . CollectLocales ( merge_equivalent_languages , locales ) ; } } return locales ;


signature:
public class CppAssetManager2 { /** * Asset . AccessMode mode ) ; */
Asset Open ( final String filename , ApkAssetsCookie cookie , Asset . AccessMode mode ) { } }

implementation: final String new_path = "assets/" + filename ; return OpenNonAsset ( new_path , cookie , mode ) ;


signature:
public class CppAssetManager2 { /** * AssetDir OpenDir ( final String dirname ) ; */
public AssetDir OpenDir ( final String dirname ) { } }

implementation:
ATRACE_CALL ( ) ; String full_path = "assets/" + dirname ; // std . unique _ ptr < SortedVector < AssetDir . FileInfo > > files =
// util . make _ unique < SortedVector < AssetDir . FileInfo > > ( ) ;
SortedVector < FileInfo > files = new SortedVector < > ( ) ; // Start from the back .
for ( CppApkAssets apk_assets : apk_assets_ ) { // auto func = [ & ] ( final String & name , FileType type ) {
ForEachFileCallback func = ( final String name , FileType type ) -> { AssetDir . FileInfo info = new FileInfo ( ) ; info . setFileName ( new String8 ( name ) ) ; info . setFileType ( type ) ; info . setSourceName ( new String8 ( apk_assets . GetPath ( ) ) ) ; files . add ( info ) ; } ; if ( ! apk_assets . ForEachFile ( full_path , func ) ) { return new AssetDir ( ) ; } } // std . unique _ ptr < AssetDir > asset _ dir = util . make _ unique < AssetDir > ( ) ;
AssetDir asset_dir = new AssetDir ( ) ; asset_dir . setFileList ( files ) ; return asset_dir ;


signature:
public class CppAssetManager2 { /** * is inconsistent for split APKs . */
public Asset OpenNonAsset ( final String filename , Asset . AccessMode mode , Ref < ApkAssetsCookie > out_cookie ) { } }

implementation: ATRACE_CALL ( ) ; for ( int i = apk_assets_ . size ( ) - 1 ; i >= 0 ; i -- ) { Asset asset = apk_assets_ . get ( i ) . Open ( filename , mode ) ; if ( isTruthy ( asset ) ) { if ( out_cookie != null ) { out_cookie . set ( ApkAssetsCookie . forInt ( i ) ) ; } return asset ; } } if ( out_cookie != null ) { out_cookie . set ( K_INVALID_COOKIE ) ; } return null ;


signature:
public class CppAssetManager2 { /** * Asset . AccessMode mode ) ; */
public Asset OpenNonAsset ( final String filename , ApkAssetsCookie cookie , Asset . AccessMode mode ) { } }

implementation: ATRACE_CALL ( ) ; if ( cookie . intValue ( ) < 0 || cookie . intValue ( ) >= apk_assets_ . size ( ) ) { return null ; } return apk_assets_ . get ( cookie . intValue ( ) ) . Open ( filename , mode ) ;


signature:
public class CppAssetManager2 { /** * int * out _ flags ) ; */
private ApkAssetsCookie FindEntry ( int resid , short density_override , boolean stop_at_first_match , final Ref < FindEntryResult > out_entry ) { } }

implementation:
ATRACE_CALL ( ) ; // Might use this if density _ override ! = 0.
ResTable_config density_override_config ; // Select our configuration or generate a density override configuration .
ResTable_config desired_config = configuration_ ; if ( density_override != 0 && density_override != configuration_ . density ) { density_override_config = configuration_ ; density_override_config . density = density_override ; desired_config = density_override_config ; } if ( ! is_valid_resid ( resid ) ) { System . err . println ( String . format ( "Invalid ID 0x%08x." , resid ) ) ; return K_INVALID_COOKIE ; } final int package_id = get_package_id ( resid ) ; final int type_idx = ( byte ) ( get_type_id ( resid ) - 1 ) ; final int entry_idx = get_entry_id ( resid ) ; final byte package_idx = package_ids_ [ package_id ] ; if ( package_idx == ( byte ) 0xff ) { System . err . println ( String . format ( "No package ID %02x found for ID 0x%08x." , package_id , resid ) ) ; return K_INVALID_COOKIE ; } final PackageGroup package_group = package_groups_ . get ( package_idx ) ; final int package_count = package_group . packages_ . size ( ) ; ApkAssetsCookie best_cookie = K_INVALID_COOKIE ; LoadedPackage best_package = null ; ResTable_type best_type = null ; ResTable_config best_config = null ; ResTable_config best_config_copy ; int best_offset = 0 ; int type_flags = 0 ; // If desired _ config is the same as the set configuration , then we can use our filtered list
// and we don ' t need to match the configurations , since they already matched .
boolean use_fast_path = desired_config == configuration_ ; for ( int pi = 0 ; pi < package_count ; pi ++ ) { ConfiguredPackage loaded_package_impl = package_group . packages_ . get ( pi ) ; LoadedPackage loaded_package = loaded_package_impl . loaded_package_ ; ApkAssetsCookie cookie = package_group . cookies_ . get ( pi ) ; // If the type IDs are offset in this package , we need to take that into account when searching
// for a type .
TypeSpec type_spec = loaded_package . GetTypeSpecByTypeIndex ( type_idx ) ; if ( Util . UNLIKELY ( type_spec == null ) ) { continue ; } int local_entry_idx = entry_idx ; // If there is an IDMAP supplied with this package , translate the entry ID .
if ( type_spec . idmap_entries != null ) { if ( ! LoadedIdmap . Lookup ( type_spec . idmap_entries , local_entry_idx , new Ref < > ( local_entry_idx ) ) ) { // There is no mapping , so the resource is not meant to be in this overlay package .
continue ; } } type_flags |= type_spec . GetFlagsForEntryIndex ( local_entry_idx ) ; // If the package is an overlay , then even configurations that are the same MUST be chosen .
boolean package_is_overlay = loaded_package . IsOverlay ( ) ; FilteredConfigGroup filtered_group = loaded_package_impl . filtered_configs_ . get ( type_idx ) ; if ( use_fast_path ) { List < ResTable_config > candidate_configs = filtered_group . configurations ; int type_count = candidate_configs . size ( ) ; for ( int i = 0 ; i < type_count ; i ++ ) { ResTable_config this_config = candidate_configs . get ( i ) ; // We can skip calling ResTable _ config . match ( ) because we know that all candidate
// configurations that do NOT match have been filtered - out .
if ( ( best_config == null || this_config . isBetterThan ( best_config , desired_config ) ) || ( package_is_overlay && this_config . compare ( best_config ) == 0 ) ) { // The configuration matches and is better than the previous selection .
// Find the entry value if it exists for this configuration .
ResTable_type type_chunk = filtered_group . types . get ( i ) ; int offset = LoadedPackage . GetEntryOffset ( type_chunk , local_entry_idx ) ; if ( offset == ResTable_type . NO_ENTRY ) { continue ; } best_cookie = cookie ; best_package = loaded_package ; best_type = type_chunk ; best_config = this_config ; best_offset = offset ; } } } else { // This is the slower path , which doesn ' t use the filtered list of configurations .
// Here we must read the ResTable _ config from the mmapped APK , convert it to host endianness
// and fill in any new fields that did not exist when the APK was compiled .
// Furthermore when selecting configurations we can ' t just record the pointer to the
// ResTable _ config , we must copy it .
// auto iter _ end = type _ spec . types + type _ spec . type _ count ;
// for ( auto iter = type _ spec . types ; iter ! = iter _ end ; + + iter ) {
for ( ResTable_type type : type_spec . types ) { ResTable_config this_config = ResTable_config . fromDtoH ( type . config ) ; if ( this_config . match ( desired_config ) ) { if ( ( best_config == null || this_config . isBetterThan ( best_config , desired_config ) ) || ( package_is_overlay && this_config . compare ( best_config ) == 0 ) ) { // The configuration matches and is better than the previous selection .
// Find the entry value if it exists for this configuration .
int offset = LoadedPackage . GetEntryOffset ( type , local_entry_idx ) ; if ( offset == ResTable_type . NO_ENTRY ) { continue ; } best_cookie = cookie ; best_package = loaded_package ; best_type = type ; best_config_copy = this_config ; best_config = best_config_copy ; best_offset = offset ; } } } } } if ( Util . UNLIKELY ( best_cookie . intValue ( ) == kInvalidCookie ) ) { return K_INVALID_COOKIE ; } ResTable_entry best_entry = LoadedPackage . GetEntryFromOffset ( best_type , best_offset ) ; if ( Util . UNLIKELY ( best_entry == null ) ) { return K_INVALID_COOKIE ; } FindEntryResult out_entry_ = new FindEntryResult ( ) ; out_entry_ . entry = best_entry ; out_entry_ . config = best_config ; out_entry_ . type_flags = type_flags ; out_entry_ . type_string_ref = new StringPoolRef ( best_package . GetTypeStringPool ( ) , best_type . id - 1 ) ; out_entry_ . entry_string_ref = new StringPoolRef ( best_package . GetKeyStringPool ( ) , best_entry . key . index ) ; out_entry_ . dynamic_ref_table = package_group . dynamic_ref_table ; out_entry . set ( out_entry_ ) ; return best_cookie ;


signature:
public class CppAssetManager2 { /** * boolean GetResourceName ( int resid , ResourceName * out _ name ) ; */
public boolean GetResourceName ( int resid , ResourceName out_name ) { } }

implementation:
final Ref < FindEntryResult > entryRef = new Ref < > ( null ) ; ApkAssetsCookie cookie = FindEntry ( resid , ( short ) 0 /* density _ override */
, true /* stop _ at _ first _ match */
, entryRef ) ; if ( cookie . intValue ( ) == kInvalidCookie ) { return false ; } final LoadedPackage package_ = apk_assets_ . get ( cookie . intValue ( ) ) . GetLoadedArsc ( ) . GetPackageById ( get_package_id ( resid ) ) ; if ( package_ == null ) { return false ; } out_name . package_ = package_ . GetPackageName ( ) ; // out _ name . package _ len = out _ name . package _ . length ( ) ;
FindEntryResult entry = entryRef . get ( ) ; out_name . type = entry . type_string_ref . string ( ) ; // out _ name . type _ len = out _ name . type = = null ? 0 : out _ name . type . length ( ) ;
// out _ name . type16 = null ;
if ( out_name . type == null ) { // out _ name . type16 = entry . type _ string _ ref . string ( ) ;
// out _ name . type _ len = out _ name . type16 = = null ? 0 : out _ name . type16 . length ( ) ;
// if ( out _ name . type16 = = null ) {
return false ; } out_name . entry = entry . entry_string_ref . string ( ) ; // out _ name . entry _ len = out _ name . entry = = null ? 0 : out _ name . entry . length ( ) ;
// out _ name . entry16 = null ;
if ( out_name . entry == null ) { // out _ name . entry16 = entry . entry _ string _ ref . string ( ) ;
// out _ name . entry _ len = out _ name . entry16 = = null ? 0 : out _ name . entry16 . length ( ) ;
// if ( out _ name . entry16 = = null ) {
return false ; } return true ;


signature:
public class CppAssetManager2 { /** * boolean GetResourceFlags ( int resid , int * out _ flags ) ; */
boolean GetResourceFlags ( int resid , Ref < Integer > out_flags ) { } }

implementation:
final Ref < FindEntryResult > entry = new Ref < > ( null ) ; ApkAssetsCookie cookie = FindEntry ( resid , ( short ) 0 /* density _ override */
, false /* stop _ at _ first _ match */
, entry ) ; if ( cookie . intValue ( ) != kInvalidCookie ) { out_flags . set ( entry . get ( ) . type_flags ) ; // this makes no sense , not a boolean :
// return cookie ;
} // this makes no sense , not a boolean :
// return kInvalidCookie ;
return cookie . intValue ( ) != kInvalidCookie ;


signature:
public class CppAssetManager2 { /** * int * out _ flags ) ; */
public ApkAssetsCookie GetResource ( int resid , boolean may_be_bag , short density_override , Ref < Res_value > out_value , final Ref < ResTable_config > out_selected_config , final Ref < Integer > out_flags ) { } }

implementation:
final Ref < FindEntryResult > entry = new Ref < > ( null ) ; ApkAssetsCookie cookie = FindEntry ( resid , density_override , false /* stop _ at _ first _ match */
, entry ) ; if ( cookie . intValue ( ) == kInvalidCookie ) { return K_INVALID_COOKIE ; } if ( isTruthy ( dtohl ( entry . get ( ) . entry . flags ) & ResTable_entry . FLAG_COMPLEX ) ) { if ( ! may_be_bag ) { System . err . println ( String . format ( "Resource %08x is a complex map type." , resid ) ) ; return K_INVALID_COOKIE ; } // Create a reference since we can ' t represent this complex type as a Res _ value .
out_value . set ( new Res_value ( ( byte ) Res_value . TYPE_REFERENCE , resid ) ) ; out_selected_config . set ( entry . get ( ) . config ) ; out_flags . set ( entry . get ( ) . type_flags ) ; return cookie ; } // final Res _ value device _ value = reinterpret _ cast < final Res _ value > (
// reinterpret _ cast < final byte * > ( entry . entry ) + dtohs ( entry . entry . size ) ) ;
// out _ value . copyFrom _ dtoh ( * device _ value ) ;
Res_value device_value = entry . get ( ) . entry . getResValue ( ) ; out_value . set ( device_value . copy ( ) ) ; // Convert the package ID to the runtime assigned package ID .
entry . get ( ) . dynamic_ref_table . lookupResourceValue ( out_value ) ; out_selected_config . set ( entry . get ( ) . config ) ; out_flags . set ( entry . get ( ) . type_flags ) ; return cookie ;


signature:
public class CppAssetManager2 { /** * int * out _ last _ reference ) ; */
public ApkAssetsCookie ResolveReference ( ApkAssetsCookie cookie , Ref < Res_value > in_out_value , final Ref < ResTable_config > in_out_selected_config , final Ref < Integer > in_out_flags , final Ref < Integer > out_last_reference ) { } }

implementation:
final int kMaxIterations = 20 ; for ( int iteration = 0 ; in_out_value . get ( ) . dataType == Res_value . TYPE_REFERENCE && in_out_value . get ( ) . data != 0 && iteration < kMaxIterations ; iteration ++ ) { out_last_reference . set ( in_out_value . get ( ) . data ) ; final Ref < Integer > new_flags = new Ref < > ( 0 ) ; cookie = GetResource ( in_out_value . get ( ) . data , true /* may _ be _ bag */
, ( short ) 0 /* density _ override */
, in_out_value , in_out_selected_config , new_flags ) ; if ( cookie . intValue ( ) == kInvalidCookie ) { return K_INVALID_COOKIE ; } if ( in_out_flags != null ) { in_out_flags . set ( in_out_flags . get ( ) | new_flags . get ( ) ) ; } if ( out_last_reference . get ( ) == in_out_value . get ( ) . data ) { // This reference can ' t be resolved , so exit now and let the caller deal with it .
return cookie ; } } return cookie ;


signature:
public class CppAssetManager2 { /** * final ResolvedBag * GetBag ( int resid ) ; */
public final ResolvedBag GetBag ( int resid ) { } }

implementation: List < Integer > found_resids = new ArrayList < > ( ) ; return GetBag ( resid , found_resids ) ;