signature: public class CppAssetManager2 { ResolvedBag GetBag ( int resid , List < Integer > child_resids ) { } }

implementation:
// ATRACE _ NAME ( " AssetManager : : GetBag " ) ;
ResolvedBag cached_iter = cached_bags_ . get ( resid ) ; if ( cached_iter != null ) { return cached_iter ; } final Ref < FindEntryResult > entryRef = new Ref < > ( null ) ; ApkAssetsCookie cookie = FindEntry ( resid , ( short ) 0 /* density _ override */
, false /* stop _ at _ first _ match */
, entryRef ) ; if ( cookie . intValue ( ) == kInvalidCookie ) { return null ; } FindEntryResult entry = entryRef . get ( ) ; // Check that the size of the entry header is at least as big as
// the desired ResTable _ map _ entry . Also verify that the entry
// was intended to be a map .
if ( dtohs ( entry . entry . size ) < ResTable_map_entry . BASE_SIZEOF || ( dtohs ( entry . entry . flags ) & ResourceTypes . ResTable_entry . FLAG_COMPLEX ) == 0 ) { // Not a bag , nothing to do .
return null ; } // final ResTable _ map _ entry map = reinterpret _ cast < final ResTable _ map _ entry * > ( entry . entry ) ;
// final ResTable _ map map _ entry =
// reinterpret _ cast < final ResTable _ map * > ( reinterpret _ cast < final byte * > ( map ) + map . size ) ;
// final ResTable _ map map _ entry _ end = map _ entry + dtohl ( map . count ) ;
final ResTable_map_entry map = new ResTable_map_entry ( entry . entry . myBuf ( ) , entry . entry . myOffset ( ) ) ; int curOffset = map . myOffset ( ) + map . size ; ResTable_map map_entry = null ; // = new ResTable _ map ( map . myBuf ( ) , curOffset ) ;
final int map_entry_end = curOffset + dtohl ( map . count ) * ResTable_map . SIZEOF ; if ( curOffset < map_entry_end ) { map_entry = new ResTable_map ( map . myBuf ( ) , curOffset ) ; } // Keep track of ids that have already been seen to prevent infinite loops caused by circular
// dependencies between bags
child_resids . add ( resid ) ; final Ref < Integer > parent_resid = new Ref < > ( dtohl ( map . parent . ident ) ) ; if ( parent_resid . get ( ) == 0 || child_resids . contains ( parent_resid . get ( ) ) ) { // There is no parent or that a circular dependency exist , meaning there is nothing to
// inherit and we can do a simple copy of the entries in the map .
final int entry_count = ( map_entry_end - curOffset ) / ResTable_map . SIZEOF ; // util . unique _ cptr < ResolvedBag > new _ bag { reinterpret _ cast < ResolvedBag * > (
// malloc ( sizeof ( ResolvedBag ) + ( entry _ count * sizeof ( ResolvedBag . Entry ) ) ) ) } ;
ResolvedBag new_bag = new ResolvedBag ( ) ; ResolvedBag . Entry [ ] new_entry = new_bag . entries = new Entry [ entry_count ] ; int i = 0 ; for ( ; curOffset < map_entry_end ; map_entry = new ResTable_map ( map_entry . myBuf ( ) , curOffset ) ) { final Ref < Integer > new_key = new Ref < > ( dtohl ( map_entry . name . ident ) ) ; if ( ! is_internal_resid ( new_key . get ( ) ) ) { // Attributes , arrays , etc don ' t have a resource id as the name . They specify
// other data , which would be wrong to change via a lookup .
if ( entry . dynamic_ref_table . lookupResourceId ( new_key ) != NO_ERROR ) { System . err . println ( String . format ( "Failed to resolve key 0x%08x in bag 0x%08x." , new_key . get ( ) , resid ) ) ; return null ; } } Entry new_entry_ = new_entry [ i ] = new Entry ( ) ; new_entry_ . cookie = cookie ; new_entry_ . key = new_key . get ( ) ; new_entry_ . key_pool = null ; new_entry_ . type_pool = null ; new_entry_ . style = resid ; new_entry_ . value = map_entry . value . copy ( ) ; final Ref < Res_value > valueRef = new Ref < > ( new_entry_ . value ) ; int err = entry . dynamic_ref_table . lookupResourceValue ( valueRef ) ; new_entry_ . value = valueRef . get ( ) ; if ( err != NO_ERROR ) { System . err . println ( String . format ( "Failed to resolve value t=0x%02x d=0x%08x for key 0x%08x." , new_entry_ . value . dataType , new_entry_ . value . data , new_key . get ( ) ) ) ; return null ; } // + + new _ entry ;
++ i ; final int size = dtohs ( map_entry . value . size ) ; // curOffset + = size + sizeof ( * map ) - sizeof ( map - > value ) ;
curOffset += size + ResTable_map . SIZEOF - Res_value . SIZEOF ; } new_bag . type_spec_flags = entry . type_flags ; new_bag . entry_count = entry_count ; ResolvedBag result = new_bag ; cached_bags_ . put ( resid , new_bag ) ; return result ; } // In case the parent is a dynamic reference , resolve it .
entry . dynamic_ref_table . lookupResourceId ( parent_resid ) ; // Get the parent and do a merge of the keys .
final ResolvedBag parent_bag = GetBag ( parent_resid . get ( ) , child_resids ) ; if ( parent_bag == null ) { // Failed to get the parent that should exist .
System . err . println ( String . format ( "Failed to find parent 0x%08x of bag 0x%08x." , parent_resid . get ( ) , resid ) ) ; return null ; } // Create the max possible entries we can make . Once we construct the bag ,
// we will realloc to fit to size .
final int max_count = parent_bag . entry_count + dtohl ( map . count ) ; // util : : unique _ cptr < ResolvedBag > new _ bag { reinterpret _ cast < ResolvedBag * > (
// malloc ( sizeof ( ResolvedBag ) + ( max _ count * sizeof ( ResolvedBag : : Entry ) ) ) ) } ;
ResolvedBag new_bag = new ResolvedBag ( ) ; new_bag . entries = new Entry [ max_count ] ; final ResolvedBag . Entry [ ] new_entry = new_bag . entries ; int newEntryIndex = 0 ; // const ResolvedBag : : Entry * parent _ entry = parent _ bag - > entries ;
int parentEntryIndex = 0 ; // final ResolvedBag . Entry parent _ entry _ end = parent _ entry + parent _ bag . entry _ count ;
final int parentEntryCount = parent_bag . entry_count ; // The keys are expected to be in sorted order . Merge the two bags .
while ( map_entry != null && map_entry . myOffset ( ) != map_entry_end && parentEntryIndex != parentEntryCount ) { final Ref < Integer > child_keyRef = new Ref < > ( dtohl ( map_entry . name . ident ) ) ; if ( ! is_internal_resid ( child_keyRef . get ( ) ) ) { if ( entry . dynamic_ref_table . lookupResourceId ( child_keyRef ) != NO_ERROR ) { System . err . println ( String . format ( "Failed to resolve key 0x%08x in bag 0x%08x." , child_keyRef . get ( ) , resid ) ) ; return null ; } } int child_key = child_keyRef . get ( ) ; Entry parent_entry = parent_bag . entries [ parentEntryIndex ] ; if ( parent_entry == null ) { parent_entry = new Entry ( ) ; } if ( child_key <= parent_entry . key ) { // Use the child key if it comes before the parent
// or is equal to the parent ( overrides ) .
Entry new_entry_ = new_entry [ newEntryIndex ] = new Entry ( ) ; new_entry_ . cookie = cookie ; new_entry_ . key = child_key ; new_entry_ . key_pool = null ; new_entry_ . type_pool = null ; new_entry_ . value = map_entry . value . copy ( ) ; new_entry_ . style = resid ; final Ref < Res_value > valueRef = new Ref < > ( new_entry_ . value ) ; int err = entry . dynamic_ref_table . lookupResourceValue ( valueRef ) ; new_entry_ . value = valueRef . get ( ) ; if ( err != NO_ERROR ) { System . err . println ( String . format ( "Failed to resolve value t=0x%02x d=0x%08x for key 0x%08x." , new_entry_ . value . dataType , new_entry_ . value . data , child_key ) ) ; return null ; } // + + map _ entry ;
map_entry = new ResTable_map ( map_entry . myBuf ( ) , map_entry . myOffset ( ) + map_entry . value . size + ResTable_map . SIZEOF - Res_value . SIZEOF ) ; } else { // Take the parent entry as - is .
// memcpy ( new _ entry , parent _ entry , sizeof ( * new _ entry ) ) ;
new_entry [ newEntryIndex ] = parent_entry . copy ( ) ; } if ( child_key >= parent_entry . key ) { // Move to the next parent entry if we used it or it was overridden .
// + + parent _ entry ;
++ parentEntryIndex ; // parent _ entry = parent _ bag . entries [ parentEntryIndex ] ;
} // Increment to the next entry to fill .
// + + new _ entry ;
++ newEntryIndex ; } // Finish the child entries if they exist .
while ( map_entry != null && map_entry . myOffset ( ) != map_entry_end ) { final Ref < Integer > new_key = new Ref < > ( map_entry . name . ident ) ; if ( ! is_internal_resid ( new_key . get ( ) ) ) { if ( entry . dynamic_ref_table . lookupResourceId ( new_key ) != NO_ERROR ) { System . err . println ( String . format ( "Failed to resolve key 0x%08x in bag 0x%08x." , new_key . get ( ) , resid ) ) ; return null ; } } Entry new_entry_ = new_entry [ newEntryIndex ] = new Entry ( ) ; new_entry_ . cookie = cookie ; new_entry_ . key = new_key . get ( ) ; new_entry_ . key_pool = null ; new_entry_ . type_pool = null ; new_entry_ . value = map_entry . value . copy ( ) ; new_entry_ . style = resid ; final Ref < Res_value > valueRef = new Ref < > ( new_entry_ . value ) ; int err = entry . dynamic_ref_table . lookupResourceValue ( valueRef ) ; new_entry_ . value = valueRef . get ( ) ; if ( err != NO_ERROR ) { System . err . println ( String . format ( "Failed to resolve value t=0x%02x d=0x%08x for key 0x%08x." , new_entry_ . value . dataType , new_entry_ . value . data , new_key . get ( ) ) ) ; return null ; } // + + map _ entry ;
map_entry = new ResTable_map ( map_entry . myBuf ( ) , map_entry . myOffset ( ) + map_entry . value . size + ResTable_map . SIZEOF - Res_value . SIZEOF ) ; // + + new _ entry ;
++ newEntryIndex ; } // Finish the parent entries if they exist .
while ( parentEntryIndex != parent_bag . entry_count ) { // Take the rest of the parent entries as - is .
// final int num _ entries _ to _ copy = parent _ entry _ end - parent _ entry ;
// final int num _ entries _ to _ copy = parent _ bag . entry _ count - parentEntryIndex ;
// memcpy ( new _ entry , parent _ entry , num _ entries _ to _ copy * sizeof ( * new _ entry ) ) ;
Entry parentEntry = parent_bag . entries [ parentEntryIndex ] ; new_entry [ newEntryIndex ] = parentEntry == null ? new Entry ( ) : parentEntry . copy ( ) ; // new _ entry + = num _ entries _ to _ copy ;
++ newEntryIndex ; ++ parentEntryIndex ; } // Resize the resulting array to fit .
// final int actual _ count = new _ entry - new _ bag . entries ;
final int actual_count = newEntryIndex ; if ( actual_count != max_count ) { // new _ bag . reset ( reinterpret _ cast < ResolvedBag * > ( realloc (
// new _ bag . release ( ) , sizeof ( ResolvedBag ) + ( actual _ count * sizeof ( ResolvedBag : : Entry ) ) ) ) ) ;
Entry [ ] resizedEntries = new Entry [ actual_count ] ; System . arraycopy ( new_bag . entries , 0 , resizedEntries , 0 , actual_count ) ; new_bag . entries = resizedEntries ; } // Combine flags from the parent and our own bag .
new_bag . type_spec_flags = entry . type_flags | parent_bag . type_spec_flags ; new_bag . entry_count = actual_count ; ResolvedBag result2 = new_bag ; // cached _ bags _ [ resid ] = std : : move ( new _ bag ) ;
cached_bags_ . put ( resid , new_bag ) ; return result2 ;


signature:
public class CppAssetManager2 { /** * final String fallback _ package = { } ) ; */
@ SuppressWarnings ( "NewApi" ) public int GetResourceId ( final String resource_name , final String fallback_type , final String fallback_package ) { } }

implementation:
final Ref < String > package_name = new Ref < > ( null ) , type = new Ref < > ( null ) , entry = new Ref < > ( null ) ; if ( ! ExtractResourceName ( resource_name , package_name , type , entry ) ) { return 0 ; } if ( entry . get ( ) . isEmpty ( ) ) { return 0 ; } if ( package_name . get ( ) . isEmpty ( ) ) { package_name . set ( fallback_package ) ; } if ( type . get ( ) . isEmpty ( ) ) { type . set ( fallback_type ) ; } String type16 = type . get ( ) ; // if ( ! Utf8ToUtf16 ( type , & type16 ) ) {
// return 0;
String entry16 = entry . get ( ) ; // if ( ! Utf8ToUtf16 ( entry , & entry16 ) ) {
// return 0;
final String kAttr16 = "attr" ; final String kAttrPrivate16 = "^attr-private" ; for ( final PackageGroup package_group : package_groups_ ) { for ( final ConfiguredPackage package_impl : package_group . packages_ ) { LoadedPackage package_ = package_impl . loaded_package_ ; if ( ! Objects . equals ( package_name . get ( ) , package_ . GetPackageName ( ) ) ) { // All packages in the same group are expected to have the same package name .
break ; } int resid = package_ . FindEntryByName ( type16 , entry16 ) ; if ( resid == 0 && Objects . equals ( kAttr16 , type16 ) ) { // Private attributes in libraries ( such as the framework ) are sometimes encoded
// under the type ' ^ attr - private ' in order to leave the ID space of public ' attr '
// free for future additions . Check ' ^ attr - private ' for the same name .
resid = package_ . FindEntryByName ( kAttrPrivate16 , entry16 ) ; } if ( resid != 0 ) { return fix_package_id ( resid , package_group . dynamic_ref_table . mAssignedPackageId ) ; } } } return 0 ;


signature:
public class CppAssetManager2 { /** * This should always be called when mutating the AssetManager ' s configuration or ApkAssets set . */
void RebuildFilterList ( ) { } }

implementation:
for ( PackageGroup group : package_groups_ ) { for ( ConfiguredPackage impl : group . packages_ ) { // / / Destroy it .
// impl . filtered _ configs _ . ~ ByteBucketArray ( ) ;
// / / Re - create it .
// new ( impl . filtered _ configs _ ) ByteBucketArray < FilteredConfigGroup > ( ) ;
impl . filtered_configs_ = new ByteBucketArray < FilteredConfigGroup > ( new FilteredConfigGroup ( ) ) { @ Override FilteredConfigGroup newInstance ( ) { return new FilteredConfigGroup ( ) ; } } ; // Create the filters here .
impl . loaded_package_ . ForEachTypeSpec ( ( TypeSpec spec , byte type_index ) -> { FilteredConfigGroup configGroup = impl . filtered_configs_ . editItemAt ( type_index ) ; // const auto iter _ end = spec - > types + spec - > type _ count ;
// for ( auto iter = spec - > types ; iter ! = iter _ end ; + + iter ) {
for ( ResTable_type iter : spec . types ) { ResTable_config this_config = ResTable_config . fromDtoH ( iter . config ) ; if ( this_config . match ( configuration_ ) ) { configGroup . configurations . add ( this_config ) ; configGroup . types . add ( iter ) ; } } } ) ; } }


signature:
public class CppAssetManager2 { /** * void InvalidateCaches ( int diff ) ; */
private void InvalidateCaches ( int diff ) { } }

implementation:
if ( diff == 0xffffffff ) { // Everything must go .
cached_bags_ . clear ( ) ; return ; } // Be more conservative with what gets purged . Only if the bag has other possible
// variations with respect to what changed ( diff ) should we remove it .
// for ( auto iter = cached _ bags _ . cbegin ( ) ; iter ! = cached _ bags _ . cend ( ) ; ) {
for ( Integer key : new ArrayList < > ( cached_bags_ . keySet ( ) ) ) { // if ( diff & iter . second . type _ spec _ flags ) {
if ( isTruthy ( diff & cached_bags_ . get ( key ) . type_spec_flags ) ) { // iter = cached _ bags _ . erase ( iter ) ;
cached_bags_ . remove ( key ) ; } }


signature:
public class CppAssetManager2 { /** * namespace android */
public List < AssetPath > getAssetPaths ( ) { } }

implementation: ArrayList < AssetPath > assetPaths = new ArrayList < > ( apk_assets_ . size ( ) ) ; for ( CppApkAssets apkAssets : apk_assets_ ) { Path path = Fs . fromUrl ( apkAssets . GetPath ( ) ) ; assetPaths . add ( new AssetPath ( path , apkAssets . GetLoadedArsc ( ) . IsSystem ( ) ) ) ; } return assetPaths ;


signature:
public class ShadowBackupManager { /** * Returns the restore token for the given package , or { @ code 0 } if the package was not restored . */
public long getPackageRestoreToken ( String packageName ) { } }

implementation: Long token = serviceState . restoredPackages . get ( packageName ) ; return token != null ? token : 0L ;


signature:
public class ShadowBackupManager { /** * Adds a restore set available to be restored . */
public void addAvailableRestoreSets ( long restoreToken , List < String > packages ) { } }

implementation: serviceState . restoreData . put ( restoreToken , packages ) ;


signature:
public class ResStringPool { /** * status _ t setTo ( const void * data , size _ t size , bool copyData = false ) ; */
public int setTo ( ByteBuffer buf , int offset , int size , boolean copyData ) { } }

implementation:
if ( ! isTruthy ( buf ) || ! isTruthy ( size ) ) { return ( mError = BAD_TYPE ) ; } uninit ( ) ; // The chunk must be at least the size of the string pool header .
if ( size < ResStringPool_header . SIZEOF ) { ALOGW ( "Bad string block: data size %zu is too small to be a string block" , size ) ; return ( mError = BAD_TYPE ) ; } // The data is at least as big as a ResChunk _ header , so we can safely validate the other
// header fields .
// ` data + size ` is safe because the source of ` size ` comes from the kernel / filesystem .
if ( validate_chunk ( new ResChunk_header ( buf , offset ) , ResStringPool_header . SIZEOF , size , "ResStringPool_header" ) != NO_ERROR ) { ALOGW ( "Bad string block: malformed block dimensions" ) ; return ( mError = BAD_TYPE ) ; } // final boolean notDeviceEndian = htods ( ( short ) 0xf0 ) ! = 0xf0;
// if ( copyData | | notDeviceEndian ) {
// mOwnedData = data ;
// if ( mOwnedData = = null ) {
// return ( mError = NO _ MEMORY ) ;
// / / memcpy ( mOwnedData , data , size ) ;
// data = mOwnedData ;
// The size has been checked , so it is safe to read the data in the ResStringPool _ header
// data structure .
mHeader = new ResStringPool_header ( buf , offset ) ; // if ( notDeviceEndian ) {
// ResStringPool _ header h = final _ cast < ResStringPool _ header * > ( mHeader ) ;
// h . header . headerSize = dtohs ( mHeader . header . headerSize ) ;
// h . header . type = dtohs ( mHeader . header . type ) ;
// h . header . size = dtohl ( mHeader . header . size ) ;
// h . stringCount = dtohl ( mHeader . stringCount ) ;
// h . styleCount = dtohl ( mHeader . styleCount ) ;
// h . flags = dtohl ( mHeader . flags ) ;
// h . stringsStart = dtohl ( mHeader . stringsStart ) ;
// h . stylesStart = dtohl ( mHeader . stylesStart ) ;
if ( mHeader . header . headerSize > mHeader . header . size || mHeader . header . size > size ) { ALOGW ( "Bad string block: header size %d or total size %d is larger than data size %d\n" , ( int ) mHeader . header . headerSize , ( int ) mHeader . header . size , ( int ) size ) ; return ( mError = BAD_TYPE ) ; } mSize = mHeader . header . size ; mEntries = new IntArray ( mHeader . myBuf ( ) , mHeader . myOffset ( ) + mHeader . header . headerSize ) ; if ( mHeader . stringCount > 0 ) { if ( ( mHeader . stringCount * 4 /* sizeof ( uint32 _ t ) */
< mHeader . stringCount ) // uint32 overflow ?
|| ( mHeader . header . headerSize + ( mHeader . stringCount * 4 /* sizeof ( uint32 _ t ) */
) ) > size ) { ALOGW ( "Bad string block: entry of %d items extends past data size %d\n" , ( int ) ( mHeader . header . headerSize + ( mHeader . stringCount * 4 /* sizeof ( uint32 _ t ) */
) ) , ( int ) size ) ; return ( mError = BAD_TYPE ) ; } int charSize ; if ( isTruthy ( mHeader . flags & ResStringPool_header . UTF8_FLAG ) ) { charSize = 1 /* sizeof ( uint8 _ t ) */
; } else { charSize = 2 /* sizeof ( uint16 _ t ) */
; } // There should be at least space for the smallest string
// (2 bytes length , null terminator ) .
if ( mHeader . stringsStart >= ( mSize - 2 /* sizeof ( uint16 _ t ) */
) ) { ALOGW ( "Bad string block: string pool starts at %d, after total size %d\n" , ( int ) mHeader . stringsStart , ( int ) mHeader . header . size ) ; return ( mError = BAD_TYPE ) ; } mStrings = mHeader . stringsStart ; if ( mHeader . styleCount == 0 ) { mStringPoolSize = ( mSize - mHeader . stringsStart ) / charSize ; } else { // check invariant : styles starts before end of data
if ( mHeader . stylesStart >= ( mSize - 2 /* sizeof ( uint16 _ t ) */
) ) { ALOGW ( "Bad style block: style block starts at %d past data size of %d\n" , ( int ) mHeader . stylesStart , ( int ) mHeader . header . size ) ; return ( mError = BAD_TYPE ) ; } // check invariant : styles follow the strings
if ( mHeader . stylesStart <= mHeader . stringsStart ) { ALOGW ( "Bad style block: style block starts at %d, before strings at %d\n" , ( int ) mHeader . stylesStart , ( int ) mHeader . stringsStart ) ; return ( mError = BAD_TYPE ) ; } mStringPoolSize = ( mHeader . stylesStart - mHeader . stringsStart ) / charSize ; } // check invariant : stringCount > 0 requires a string pool to exist
if ( mStringPoolSize == 0 ) { ALOGW ( "Bad string block: stringCount is %d but pool size is 0\n" , ( int ) mHeader . stringCount ) ; return ( mError = BAD_TYPE ) ; } // if ( notDeviceEndian ) {
// int i ;
// uint32 _ t * e = final _ cast < uint32 _ t * > ( mEntries ) ;
// for ( i = 0 ; i < mHeader . stringCount ; i + + ) {
// e [ i ] = dtohl ( mEntries [ i ] ) ;
// if ( ! ( mHeader . flags & ResStringPool _ header : : UTF8 _ FLAG ) ) {
// final uint16 _ t * strings = ( final uint16 _ t * ) mStrings ;
// uint16 _ t * s = final _ cast < uint16 _ t * > ( strings ) ;
// for ( i = 0 ; i < mStringPoolSize ; i + + ) {
// s [ i ] = dtohs ( strings [ i ] ) ;
// if ( ( mHeader - > flags & ResStringPool _ header : : UTF8 _ FLAG & &
// ( ( uint8 _ t * ) mStrings ) [ mStringPoolSize - 1 ] ! = 0 ) | |
// ( ! ( mHeader - > flags & ResStringPool _ header : : UTF8 _ FLAG ) & &
// ( ( uint16 _ t * ) mStrings ) [ mStringPoolSize - 1 ] ! = 0 ) ) {
if ( ( isTruthy ( mHeader . flags & ResStringPool_header . UTF8_FLAG ) && ( mHeader . getByte ( mStrings + mStringPoolSize - 1 ) != 0 ) ) || ( ! isTruthy ( mHeader . flags & ResStringPool_header . UTF8_FLAG ) && ( mHeader . getShort ( mStrings + mStringPoolSize * 2 - 2 ) != 0 ) ) ) { ALOGW ( "Bad string block: last string is not 0-terminated\n" ) ; return ( mError = BAD_TYPE ) ; } } else { mStrings = - 1 ; mStringPoolSize = 0 ; } if ( mHeader . styleCount > 0 ) { mEntryStyles = new IntArray ( mEntries . myBuf ( ) , mEntries . myOffset ( ) + mHeader . stringCount * SIZEOF_INT ) ; // invariant : integer overflow in calculating mEntryStyles
if ( mEntryStyles . myOffset ( ) < mEntries . myOffset ( ) ) { ALOGW ( "Bad string block: integer overflow finding styles\n" ) ; return ( mError = BAD_TYPE ) ; } // if ( ( ( const uint8 _ t * ) mEntryStyles - ( const uint8 _ t * ) mHeader ) > ( int ) size ) {
if ( ( mEntryStyles . myOffset ( ) - mHeader . myOffset ( ) ) > ( int ) size ) { ALOGW ( "Bad string block: entry of %d styles extends past data size %d\n" , ( int ) ( mEntryStyles . myOffset ( ) ) , ( int ) size ) ; return ( mError = BAD_TYPE ) ; } mStyles = mHeader . stylesStart ; if ( mHeader . stylesStart >= mHeader . header . size ) { ALOGW ( "Bad string block: style pool starts %d, after total size %d\n" , ( int ) mHeader . stylesStart , ( int ) mHeader . header . size ) ; return ( mError = BAD_TYPE ) ; } mStylePoolSize = ( mHeader . header . size - mHeader . stylesStart ) /* / sizeof ( uint32 _ t ) */
; // if ( notDeviceEndian ) {
// size _ t i ;
// uint32 _ t * e = final _ cast < uint32 _ t * > ( mEntryStyles ) ;
// for ( i = 0 ; i < mHeader . styleCount ; i + + ) {
// e [ i ] = dtohl ( mEntryStyles [ i ] ) ;
// uint32 _ t * s = final _ cast < uint32 _ t * > ( mStyles ) ;
// for ( i = 0 ; i < mStylePoolSize ; i + + ) {
// s [ i ] = dtohl ( mStyles [ i ] ) ;
// final ResStringPool _ span endSpan = {
// { htodl ( ResStringPool _ span . END ) } ,
// htodl ( ResStringPool _ span . END ) , htodl ( ResStringPool _ span . END )
// if ( memcmp ( & mStyles [ mStylePoolSize - ( sizeof ( endSpan ) / sizeof ( uint32 _ t ) ) ] ,
// & endSpan , sizeof ( endSpan ) ) ! = 0 ) {
ResStringPool_span endSpan = new ResStringPool_span ( buf , mHeader . myOffset ( ) + mStyles + ( mStylePoolSize - ResStringPool_span . SIZEOF ) ) ; if ( ! endSpan . isEnd ( ) ) { ALOGW ( "Bad string block: last style is not 0xFFFFFFFF-terminated\n" ) ; return ( mError = BAD_TYPE ) ; } } else { mEntryStyles = null ; mStyles = 0 ; mStylePoolSize = 0 ; } return ( mError = NO_ERROR ) ;


signature:
public class ShadowPausedLooper { /** * compatibility for now */
@ Override public void runPaused ( Runnable runnable ) { } }

implementation:
if ( isPaused && Thread . currentThread ( ) == realLooper . getThread ( ) ) { // just run
runnable . run ( ) ; } else { throw new UnsupportedOperationException ( ) ; }


signature:
public class ShadowPausedLooper { /** * Executes the given runnable on the loopers thread , and waits for it to complete . */
private void executeOnLooper ( ControlRunnable runnable ) { } }

implementation: if ( Thread . currentThread ( ) == realLooper . getThread ( ) ) { runnable . run ( ) ; } else { if ( realLooper . equals ( Looper . getMainLooper ( ) ) ) { throw new UnsupportedOperationException ( "main looper can only be controlled from main thread" ) ; } looperExecutor . execute ( runnable ) ; runnable . waitTillComplete ( ) ; }


signature:
public class AttributeResolution10 { /** * ` out _ indices ` may be nullptr . */
public static boolean ResolveAttrs ( Theme theme , int def_style_attr , int def_style_res , int [ ] src_values , int src_values_length , int [ ] attrs , int attrs_length , int [ ] out_values , int [ ] out_indices ) { } }

implementation:
if ( kDebugStyles ) { ALOGI ( "APPLY STYLE: theme=0x%p defStyleAttr=0x%x defStyleRes=0x%x" , theme , def_style_attr , def_style_res ) ; } CppAssetManager2 assetmanager = theme . GetAssetManager ( ) ; ResTable_config config = new ResTable_config ( ) ; Res_value value ; int indicesIdx = 0 ; // Load default style from attribute , if specified . . .
final Ref < Integer > def_style_flags = new Ref < > ( 0 ) ; if ( def_style_attr != 0 ) { final Ref < Res_value > valueRef = new Ref < > ( null ) ; if ( theme . GetAttribute ( def_style_attr , valueRef , def_style_flags ) . intValue ( ) != kInvalidCookie ) { value = valueRef . get ( ) ; if ( value . dataType == Res_value . TYPE_REFERENCE ) { def_style_res = value . data ; } } } // Retrieve the default style bag , if requested .
ResolvedBag default_style_bag = null ; if ( def_style_res != 0 ) { default_style_bag = assetmanager . GetBag ( def_style_res ) ; if ( default_style_bag != null ) { def_style_flags . set ( def_style_flags . get ( ) | default_style_bag . type_spec_flags ) ; } } BagAttributeFinder def_style_attr_finder = new BagAttributeFinder ( default_style_bag ) ; // Now iterate through all of the attributes that the client has requested ,
// filling in each with whatever data we can find .
int destOffset = 0 ; for ( int ii = 0 ; ii < attrs_length ; ii ++ ) { final int cur_ident = attrs [ ii ] ; if ( kDebugStyles ) { ALOGI ( "RETRIEVING ATTR 0x%08x..." , cur_ident ) ; } ApkAssetsCookie cookie = K_INVALID_COOKIE ; int type_set_flags = 0 ; value = Res_value . NULL_VALUE ; config . density = 0 ; // Try to find a value for this attribute . . . we prioritize values
// coming from , first XML attributes , then XML style , then default
// style , and finally the theme .
// Retrieve the current input value if available .
if ( src_values_length > 0 && src_values [ ii ] != 0 ) { value = new Res_value ( ( byte ) Res_value . TYPE_ATTRIBUTE , src_values [ ii ] ) ; if ( kDebugStyles ) { ALOGI ( "-> From values: type=0x%x, data=0x%08x" , value . dataType , value . data ) ; } } else { final Entry entry = def_style_attr_finder . Find ( cur_ident ) ; if ( entry != null ) { cookie = entry . cookie ; type_set_flags = def_style_flags . get ( ) ; value = entry . value ; if ( kDebugStyles ) { ALOGI ( "-> From def style: type=0x%x, data=0x%08x" , value . dataType , value . data ) ; } } } int resid = 0 ; final Ref < Res_value > valueRef = new Ref < > ( value ) ; final Ref < Integer > residRef = new Ref < > ( resid ) ; final Ref < Integer > type_set_flagsRef = new Ref < > ( type_set_flags ) ; final Ref < ResTable_config > configRef = new Ref < > ( config ) ; if ( value . dataType != Res_value . TYPE_NULL ) { // Take care of resolving the found resource to its final value .
ApkAssetsCookie new_cookie = theme . ResolveAttributeReference ( cookie , valueRef , configRef , type_set_flagsRef , residRef ) ; if ( new_cookie . intValue ( ) != kInvalidCookie ) { cookie = new_cookie ; } if ( kDebugStyles ) { ALOGI ( "-> Resolved attr: type=0x%x, data=0x%08x" , value . dataType , value . data ) ; } } else if ( value . data != Res_value . DATA_NULL_EMPTY ) { // If we still don ' t have a value for this attribute , try to find it in the theme !
ApkAssetsCookie new_cookie = theme . GetAttribute ( cur_ident , valueRef , type_set_flagsRef ) ; if ( new_cookie . intValue ( ) != kInvalidCookie ) { if ( kDebugStyles ) { ALOGI ( "-> From theme: type=0x%x, data=0x%08x" , value . dataType , value . data ) ; } new_cookie = assetmanager . ResolveReference ( new_cookie , valueRef , configRef , type_set_flagsRef , residRef ) ; if ( new_cookie . intValue ( ) != kInvalidCookie ) { cookie = new_cookie ; } if ( kDebugStyles ) { ALOGI ( "-> Resolved theme: type=0x%x, data=0x%08x" , value . dataType , value . data ) ; } } } value = valueRef . get ( ) ; resid = residRef . get ( ) ; type_set_flags = type_set_flagsRef . get ( ) ; config = configRef . get ( ) ; // Deal with the special @ null value - - it turns back to TYPE _ NULL .
if ( value . dataType == Res_value . TYPE_REFERENCE && value . data == 0 ) { if ( kDebugStyles ) { ALOGI ( "-> Setting to @null!" ) ; } value = Res_value . NULL_VALUE ; cookie = K_INVALID_COOKIE ; } if ( kDebugStyles ) { ALOGI ( "Attribute 0x%08x: type=0x%x, data=0x%08x" , cur_ident , value . dataType , value . data ) ; } // Write the final value back to Java .
out_values [ destOffset + STYLE_TYPE ] = value . dataType ; out_values [ destOffset + STYLE_DATA ] = value . data ; out_values [ destOffset + STYLE_ASSET_COOKIE ] = ApkAssetsCookieToJavaCookie ( cookie ) ; out_values [ destOffset + STYLE_RESOURCE_ID ] = resid ; out_values [ destOffset + STYLE_CHANGING_CONFIGURATIONS ] = type_set_flags ; out_values [ destOffset + STYLE_DENSITY ] = config . density ; if ( out_indices != null && value . dataType != Res_value . TYPE_NULL ) { indicesIdx ++ ; out_indices [ indicesIdx ] = ii ; } destOffset += STYLE_NUM_ENTRIES ; } if ( out_indices != null ) { out_indices [ 0 ] = indicesIdx ; } return true ;


signature:
public class ShadowParcel { /** * this needs to start above 0 , which is a magic number to Parcel */
@ Implementation ( maxSdk = JELLY_BEAN_MR1 ) @ SuppressWarnings ( "TypeParameterUnusedInFormals" ) protected < T extends Parcelable > T readParcelable ( ClassLoader loader ) { } }

implementation:
// prior to JB MR2 , readParcelableCreator ( ) is inlined here .
Parcelable . Creator < ? > creator = readParcelableCreator ( loader ) ; if ( creator == null ) { return null ; } if ( creator instanceof Parcelable . ClassLoaderCreator < ? > ) { Parcelable . ClassLoaderCreator < ? > classLoaderCreator = ( Parcelable . ClassLoaderCreator < ? > ) creator ; return ( T ) classLoaderCreator . createFromParcel ( realObject , loader ) ; } return ( T ) creator . createFromParcel ( realObject ) ;


signature:
public class ShadowParcel { /** * non - existent - in - JDK java . util . Arrays . checkOffsetAndCount method . */
@ Implementation ( minSdk = M ) protected void writeBlob ( byte [ ] b , int offset , int len ) { } }

implementation: if ( b == null ) { realObject . writeInt ( - 1 ) ; return ; } throwsIfOutOfBounds ( b . length , offset , len ) ; long nativePtr = ReflectionHelpers . getField ( realObject , "mNativePtr" ) ; nativeWriteBlob ( nativePtr , b , offset , len ) ;


signature:
public class ShadowParcel { /** * nativeWriteBlob was introduced in lollipop , thus no need for a int nativePtr variant */
@ Implementation ( minSdk = LOLLIPOP ) protected static void nativeWriteBlob ( long nativePtr , byte [ ] b , int offset , int len ) { } }

implementation: nativeWriteByteArray ( nativePtr , b , offset , len ) ;


signature:
public class ShadowParcel { /** * Converts a ByteBuffer to a raw byte array . This method should be symmetrical with
 * fromByteArray . */
public byte [ ] toByteArray ( ) { } }

implementation:
int oldDataPosition = dataPosition ; try { ByteArrayOutputStream bos = new ByteArrayOutputStream ( ) ; ObjectOutputStream oos = new ObjectOutputStream ( bos ) ; // NOTE : Serializing the data array would be simpler , and serialization would actually
// preserve reference equality between entries . However , the length - encoded format here
// preserves the previous format , which some tests appear to rely on .
List < FakeEncodedItem > entries = new ArrayList < > ( ) ; // NOTE : Use readNextItem to scan so the contents can be proactively validated .
dataPosition = 0 ; while ( dataPosition < dataSize ) { entries . add ( readNextItem ( Object . class ) ) ; } oos . writeInt ( entries . size ( ) ) ; for ( FakeEncodedItem item : entries ) { oos . writeInt ( item . sizeBytes ) ; oos . writeObject ( item . value ) ; } oos . flush ( ) ; return bos . toByteArray ( ) ; } catch ( IOException e ) { throw new UnreliableBehaviorError ( "ErrorProne unable to serialize its custom format" , e ) ; } finally { dataPosition = oldDataPosition ; }


signature:
public class ShadowParcel { /** * Sets the current data position .
 * @ param pos
 * Desired position in bytes */
public void setDataPosition ( int pos ) { } }

implementation:
if ( pos > dataSize ) { // NOTE : Real parcel ignores this until a write occurs .
throw new UnreliableBehaviorError ( pos + " greater than dataSize " + dataSize ) ; } dataPosition = pos ; failNextReadIfPastEnd = false ;


signature:
public class ShadowParcel { /** * Ensures that the next sizeBytes are all the initial value we read .
 * < p > This detects :
 * < ul >
 * < li > Reading an item , but not starting at its start position
 * < li > Reading items that were truncated by setSize
 * < li > Reading items that were partially overwritten by another
 * < / ul > */
private void checkConsistentReadAndIncrementPosition ( Class < ? > clazz , FakeEncodedItem item ) { } }

implementation: int endPosition = dataPosition + item . sizeBytes ; for ( int i = dataPosition ; i < endPosition ; i ++ ) { FakeEncodedItem foundItemItem = i < dataSize ? data [ i ] : null ; if ( foundItemItem != item ) { throw new UnreliableBehaviorError ( clazz , dataPosition , item , String . format ( Locale . US , "but [%s] interrupts it at position %d" , foundItemItem == null ? "uninitialized data or the end of the buffer" : foundItemItem . value , i ) ) ; } } dataPosition = Math . min ( dataSize , dataPosition + item . sizeBytes ) ;


signature:
public class ShadowParcel { /** * Returns the item at the current position , or null if uninitialized or null . */
private Object peek ( ) { } }

implementation: return dataPosition < dataSize && data [ dataPosition ] != null ? data [ dataPosition ] . value : null ;


signature:
public class ShadowParcel { /** * Reads a complete item in the byte buffer .
 * @ param clazz this is the type that is being read , but not checked in this method
 * @ return null if the default value should be returned , otherwise the item holding the data */
private < T > FakeEncodedItem readNextItem ( Class < T > clazz ) { } }

implementation:
FakeEncodedItem item = data [ dataPosition ] ; if ( item == null ) { // While Parcel will treat these as zeros , in tests , this is almost always an error .
throw new UnreliableBehaviorError ( "Reading uninitialized data at position " + dataPosition ) ; } checkConsistentReadAndIncrementPosition ( clazz , item ) ; return item ;


signature:
public class ShadowParcel { /** * Reads the next value in the byte buffer of a specified type .
 * @ param pastEndValue value to return when reading past the end of the buffer
 * @ param clazz this is the type that is being read , but not checked in this method
 * @ param allowNull whether null values are permitted */
private < T > T readValue ( T pastEndValue , Class < T > clazz , boolean allowNull ) { } }

implementation:
if ( dataPosition >= dataSize ) { // Normally , reading past the end is permitted , and returns the default values . However ,
// writing to a parcel then reading without setting the position back to 0 is an incredibly
// common error to make in tests , and should never really happen in production code , so
// this shadow will fail in this condition .
if ( failNextReadIfPastEnd ) { throw new UnreliableBehaviorError ( "Did you forget to setDataPosition(0) before reading the parcel?" ) ; } return pastEndValue ; } int startPosition = dataPosition ; FakeEncodedItem item = readNextItem ( clazz ) ; if ( item == null ) { return pastEndValue ; } else if ( item . value == null && allowNull ) { return null ; } else if ( clazz . isInstance ( item . value ) ) { return clazz . cast ( item . value ) ; } else { // Numerous existing tests rely on ShadowParcel throwing RuntimeException and catching
// them . Many of these tests are trying to test what happens when an invalid Parcel is
// provided . However , Android has no concept of an " invalid parcel " because Parcel will
// happily return garbage if you ask for it . The only runtime exceptions are thrown on
// array length mismatches , or higher - level APIs like Parcelable ( which has its own safety
// checks ) . Tests trying to test error - handling behavior should instead craft a Parcel
// that specifically triggers a BadParcelableException .
throw new RuntimeException ( new UnreliableBehaviorError ( clazz , startPosition , item , "and it is non-portable to reinterpret it" ) ) ; }


signature:
public class ShadowParcel { /** * Determines if there is a sequence of castable zeroes , and consumes them .
 * < p > This is the only exception for strong typing , because zero bytes are portable and
 * unambiguous . There are a few situations where well - written code can rely on this , so it is
 * worthwhile making a special exception for . This tolerates partially - overwritten and truncated
 * values if all bytes are zero . */
private boolean readZeroes ( int bytes ) { } }

implementation:
int endPosition = dataPosition + bytes ; if ( endPosition > dataSize ) { return false ; } for ( int i = dataPosition ; i < endPosition ; i ++ ) { if ( data [ i ] == null || ! data [ i ] . isEncodedAsAllZeroBytes ) { return false ; } } // Note in this case we short - circuit other verification - - even if we are reading weirdly
// clobbered zeroes , they ' re still zeroes . Future reads might fail , though .
dataPosition = endPosition ; return true ;


signature:
public class ShadowParcel { /** * Reads a primitive , which may reinterpret zeros of other types .
 * @ param defaultSizeBytes if reinterpreting zeros , the number of bytes to consume
 * @ param defaultValue the default value for zeros or reading past the end
 * @ param clazz this is the type that is being read , but not checked in this method */
private < T > T readPrimitive ( int defaultSizeBytes , T defaultValue , Class < T > clazz ) { } }

implementation:
// Check for zeroes first , since partially - overwritten values are not an error for zeroes .
if ( readZeroes ( defaultSizeBytes ) ) { return defaultValue ; } return readValue ( defaultValue , clazz , /* allowNull = */
false ) ;


signature:
public class ShadowParcel { /** * Writes an encoded item directly , bypassing alignment , and possibly repeating an item . */
private void writeItem ( FakeEncodedItem item ) { } }

implementation:
int endPosition = dataPosition + item . sizeBytes ; if ( endPosition > data . length ) { // Parcel grows by 3/2 of the new size .
setDataCapacityAtLeast ( endPosition * 3 / 2 ) ; } if ( endPosition > dataSize ) { failNextReadIfPastEnd = true ; dataSize = endPosition ; } Arrays . fill ( data , dataPosition , endPosition , item ) ; dataPosition = endPosition ;


signature:
public class ShadowKeyguardManager { /** * Sets whether the device keyguard is locked or not . This affects the value to be returned by
 * { @ link # isKeyguardLocked ( ) } and also invokes callbacks set in
 * { @ link KeyguardManager # requestDismissKeyguard ( ) } .
 * @ param isKeyguardLocked true to lock the keyguard . If a KeyguardDismissCallback is set will
 * fire { @ link KeyguardDismissCallback # onDismissCancelled ( ) } or false to unlock and dismiss the
 * keyguard firing { @ link KeyguardDismissCallback # onDismissSucceeded ( ) } if a
 * KeyguardDismissCallback is set . */
public void setKeyguardLocked ( boolean isKeyguardLocked ) { } }

implementation: this . isKeyguardLocked = isKeyguardLocked ; if ( callback != null ) { if ( isKeyguardLocked ) { callback . onDismissCancelled ( ) ; } else { callback . onDismissSucceeded ( ) ; } callback = null ; }


signature:
public class ShadowKeyguardManager { /** * For tests on Android > = M , sets the value to be returned by { @ link # isDeviceSecure ( int ) } .
 * @ see # isDeviceSecure ( int ) */
public void setIsDeviceSecure ( int userId , boolean isDeviceSecure ) { } }

implementation: if ( isDeviceSecure ) { deviceSecureForUsers . add ( userId ) ; } else { deviceSecureForUsers . remove ( userId ) ; }


signature:
public class ShadowKeyguardManager { /** * For tests on Android > = L MR1 , sets the value to be returned by { @ link # isDeviceLocked ( int ) } .
 * @ see # isDeviceLocked ( int ) */
public void setIsDeviceLocked ( int userId , boolean isLocked ) { } }

implementation: if ( isLocked ) { deviceLockedForUsers . add ( userId ) ; } else { deviceLockedForUsers . remove ( userId ) ; }


signature:
public class ShadowKeyguardManager { /** * Returns the intent set via
 * { @ link # setConfirmFactoryResetCredentialIntent ( Intent ) } , otherwise null . */
@ Implementation ( minSdk = O_MR1 ) protected Intent createConfirmFactoryResetCredentialIntent ( CharSequence title , CharSequence description , CharSequence alternateButtonLabel ) { } }


signature: public class ShadowVectorDrawable { @ Implementation protected static boolean nGetGroupProperties ( long groupPtr , float [ ] properties , int length ) { } }

implementation: if ( length != 7 ) return false ; Group group = getGroup ( groupPtr ) ; properties [ 0 ] = group . rotation ; properties [ 1 ] = group . pivotX ; properties [ 2 ] = group . pivotY ; properties [ 3 ] = group . scaleX ; properties [ 4 ] = group . scaleY ; properties [ 5 ] = group . translateX ; properties [ 6 ] = group . translateY ; return true ;


signature:
public class ShadowServiceManager { /** * Returns the binder associated with the given system service . If the given service is set to
 * unavailable in { @ link # setServiceAvailability } , { @ code null } will be returned . */
@ Implementation protected static IBinder getService ( String name ) { } }

implementation: if ( unavailableServices . contains ( name ) ) { return null ; } return SERVICES . get ( name ) ;


signature:
public class ShadowServiceManager { /** * Sets the availability of the given system service . If the service is set as unavailable ,
 * subsequent calls to { @ link Context # getSystemService } for that service will return { @ code null } . */
public static void setServiceAvailability ( String service , boolean available ) { } }

implementation: if ( available ) { unavailableServices . remove ( service ) ; } else { unavailableServices . add ( service ) ; }


signature:
public class ShadowPowerManager { /** * Discards the most recent { @ code PowerManager . WakeLock } s */
@ Resetter public static void reset ( ) { } }

implementation: ShadowApplication shadowApplication = ShadowApplication . getInstance ( ) ; if ( shadowApplication != null ) { shadowApplication . clearWakeLocks ( ) ; }


signature:
public class ShadowLegacyChoreographer { /** * The default implementation will call { @ link # postCallbackDelayed ( int , Runnable , Object , long ) }
 * with no delay . { @ link android . animation . AnimationHandler } calls this method to schedule
 * animation updates infinitely . Because during a Robolectric test the system time is paused and
 * execution of the event loop is invoked for each test instruction , the behavior of
 * AnimationHandler would result in endless looping ( the execution of the task results in a new
 * animation task created and scheduled to the front of the event loop queue ) .
 * < p > To prevent endless looping , a test may call { @ link # setPostCallbackDelay ( int ) } to specify a
 * small delay when animation is scheduled .
 * @ see # setPostCallbackDelay ( int ) */
@ Implementation protected void postCallback ( int callbackType , Runnable action , Object token ) { } }

implementation: postCallbackDelayed ( callbackType , action , token , postCallbackDelayMillis ) ;


signature:
public class DeviceConfig { /** * Makes a given configuration , which may have undefined values , conform to the rules declared
 * [ here ] ( http : / / robolectric . org / device - configuration / ) . */
static void applyRules ( Configuration configuration , DisplayMetrics displayMetrics , int apiLevel ) { } }

implementation:
Locale locale = getLocale ( configuration , apiLevel ) ; String language = locale == null ? "" : locale . getLanguage ( ) ; if ( language . isEmpty ( ) ) { language = "en" ; String country = locale == null ? "" : locale . getCountry ( ) ; if ( country . isEmpty ( ) ) { country = "us" ; } locale = new Locale ( language , country ) ; setLocale ( apiLevel , configuration , locale ) ; } if ( apiLevel <= ConfigDescription . SDK_JELLY_BEAN && getScreenLayoutLayoutDir ( configuration ) == Configuration . SCREENLAYOUT_LAYOUTDIR_UNDEFINED ) { setScreenLayoutLayoutDir ( configuration , Configuration . SCREENLAYOUT_LAYOUTDIR_LTR ) ; } ScreenSize requestedScreenSize = getScreenSize ( configuration ) ; if ( requestedScreenSize == null ) { requestedScreenSize = DEFAULT_SCREEN_SIZE ; } if ( configuration . orientation == Configuration . ORIENTATION_UNDEFINED && configuration . screenWidthDp != 0 && configuration . screenHeightDp != 0 ) { configuration . orientation = ( configuration . screenWidthDp > configuration . screenHeightDp ) ? Configuration . ORIENTATION_LANDSCAPE : Configuration . ORIENTATION_PORTRAIT ; } if ( configuration . screenWidthDp == 0 ) { configuration . screenWidthDp = requestedScreenSize . width ; } if ( configuration . screenHeightDp == 0 ) { configuration . screenHeightDp = requestedScreenSize . height ; if ( ( configuration . screenLayout & Configuration . SCREENLAYOUT_LONG_MASK ) == Configuration . SCREENLAYOUT_LONG_YES ) { configuration . screenHeightDp = ( int ) ( configuration . screenHeightDp * 1.25f ) ; } } int lesserDimenPx = Math . min ( configuration . screenWidthDp , configuration . screenHeightDp ) ; int greaterDimenPx = Math . max ( configuration . screenWidthDp , configuration . screenHeightDp ) ; if ( configuration . smallestScreenWidthDp == 0 ) { configuration . smallestScreenWidthDp = lesserDimenPx ; } if ( getScreenLayoutSize ( configuration ) == Configuration . SCREENLAYOUT_SIZE_UNDEFINED ) { ScreenSize screenSize = ScreenSize . match ( configuration . screenWidthDp , configuration . screenHeightDp ) ; setScreenLayoutSize ( configuration , screenSize . configValue ) ; } if ( getScreenLayoutLong ( configuration ) == Configuration . SCREENLAYOUT_LONG_UNDEFINED ) { setScreenLayoutLong ( configuration , ( ( float ) greaterDimenPx ) / lesserDimenPx >= 1.75 ? Configuration . SCREENLAYOUT_LONG_YES : Configuration . SCREENLAYOUT_LONG_NO ) ; } if ( getScreenLayoutRound ( configuration ) == Configuration . SCREENLAYOUT_ROUND_UNDEFINED ) { setScreenLayoutRound ( configuration , Configuration . SCREENLAYOUT_ROUND_NO ) ; } if ( configuration . orientation == Configuration . ORIENTATION_UNDEFINED ) { configuration . orientation = configuration . screenWidthDp > configuration . screenHeightDp ? Configuration . ORIENTATION_LANDSCAPE : Configuration . ORIENTATION_PORTRAIT ; } else if ( configuration . orientation == Configuration . ORIENTATION_PORTRAIT && configuration . screenWidthDp > configuration . screenHeightDp ) { swapXY ( configuration ) ; } else if ( configuration . orientation == Configuration . ORIENTATION_LANDSCAPE && configuration . screenWidthDp < configuration . screenHeightDp ) { swapXY ( configuration ) ; } if ( getUiModeType ( configuration ) == Configuration . UI_MODE_TYPE_UNDEFINED ) { setUiModeType ( configuration , Configuration . UI_MODE_TYPE_NORMAL ) ; } if ( getUiModeNight ( configuration ) == Configuration . UI_MODE_NIGHT_UNDEFINED ) { setUiModeNight ( configuration , Configuration . UI_MODE_NIGHT_NO ) ; } switch ( displayMetrics . densityDpi ) { case ResTable_config . DENSITY_DPI_ANY : throw new IllegalArgumentException ( "'anydpi' isn't actually a dpi" ) ; case ResTable_config . DENSITY_DPI_NONE : throw new IllegalArgumentException ( "'nodpi' isn't actually a dpi" ) ; case ResTable_config . DENSITY_DPI_UNDEFINED : // DisplayMetrics . DENSITY _ DEFAULT is mdpi
setDensity ( DEFAULT_DENSITY , apiLevel , configuration , displayMetrics ) ; } if ( configuration . touchscreen == Configuration . TOUCHSCREEN_UNDEFINED ) { configuration . touchscreen = Configuration . TOUCHSCREEN_FINGER ; } if ( configuration . keyboardHidden == Configuration . KEYBOARDHIDDEN_UNDEFINED ) { configuration . keyboardHidden = Configuration . KEYBOARDHIDDEN_SOFT ; } if ( configuration . keyboard == Configuration . KEYBOARD_UNDEFINED ) { configuration . keyboard = Configuration . KEYBOARD_NOKEYS ; } if ( configuration . navigationHidden == Configuration . NAVIGATIONHIDDEN_UNDEFINED ) { configuration . navigationHidden = Configuration . NAVIGATIONHIDDEN_YES ; } if ( configuration . navigation == Configuration . NAVIGATION_UNDEFINED ) { configuration . navigation = Configuration . NAVIGATION_NONAV ; } if ( apiLevel >= VERSION_CODES . O ) { if ( getColorModeGamut ( configuration ) == Configuration . COLOR_MODE_WIDE_COLOR_GAMUT_UNDEFINED ) { setColorModeGamut ( configuration , Configuration . COLOR_MODE_WIDE_COLOR_GAMUT_NO ) ; } if ( getColorModeHdr ( configuration ) == Configuration . COLOR_MODE_HDR_UNDEFINED ) { setColorModeHdr ( configuration , Configuration . COLOR_MODE_HDR_NO ) ; } }


signature:
public class ShadowAccessibilityWindowInfo { /** * Check for leaked objects that were { @ code obtain } ed but never
 * { @ code recycle } d .
 * @ param printUnrecycledWindowsToSystemErr - if true , stack traces of calls
 * to { @ code obtain } that lack matching calls to { @ code recycle } are
 * dumped to System . err .
 * @ return { @ code true } if there are unrecycled windows */
public static boolean areThereUnrecycledWindows ( boolean printUnrecycledWindowsToSystemErr ) { } }

implementation: if ( printUnrecycledWindowsToSystemErr ) { for ( final StrictEqualityWindowWrapper wrapper : obtainedInstances . keySet ( ) ) { final ShadowAccessibilityWindowInfo shadow = Shadow . extract ( wrapper . mInfo ) ; System . err . println ( String . format ( "Leaked type = %d, id = %d. Stack trace:" , shadow . getType ( ) , shadow . getId ( ) ) ) ; for ( final StackTraceElement stackTraceElement : obtainedInstances . get ( wrapper ) ) { System . err . println ( stackTraceElement . toString ( ) ) ; } } } return ( obtainedInstances . size ( ) != 0 ) ;


signature:
public class ShadowPausedMessage { /** * TODO : reconsider this being exposed as a public method */
@ Override @ Implementation ( minSdk = LOLLIPOP ) public void recycleUnchecked ( ) { } }

implementation: if ( Build . VERSION . SDK_INT >= LOLLIPOP ) { directlyOn ( realObject , Message . class , "recycleUnchecked" ) ; } else { directlyOn ( realObject , Message . class ) . recycle ( ) ; }


signature:
public class AccessibilityUtil { /** * Check a hierarchy of { @ code View } s for accessibility . Only performs checks if ( in decreasing
 * priority order ) accessibility checking is enabled using an { @ link AccessibilityChecks }
 * annotation , if the system property { @ code robolectric . accessibility . enablechecks } is set to
 * { @ code true } , or if the environment variable { @ code robolectric . accessibility . enablechecks }
 * is set to { @ code true } .
 * @ param view The { @ code View } to examine
 * @ return A list of results from the check . If there are no results or checking is disabled ,
 * the list is empty . */
public static List < AccessibilityViewCheckResult > checkViewIfCheckingEnabled ( View view ) { } }

implementation: AccessibilityChecks classChecksAnnotation = getAnnotation ( ) ; if ( ! isAccessibilityCheckingEnabled ( classChecksAnnotation ) ) { return Collections . emptyList ( ) ; } return checkView ( view ) ;


signature:
public class AccessibilityUtil { /** * Check a hierarchy of { @ code View } s for accessibility . Only performs checks if ( in decreasing
 * priority order ) accessibility checking is enabled using an { @ link AccessibilityChecks }
 * annotation , if the system property { @ code robolectric . accessibility . enablechecks } is set to
 * { @ code true } , or if the environment variable { @ code robolectric . accessibility . enablechecks }
 * is set to { @ code true } .
 * Implicitly calls { code setThrowExceptionForErrors ( false ) } to disable exception throwing . This
 * method is deprecated , both because of this side effect and because the other methods offer
 * more control over execution .
 * @ param view The { @ code View } to examine
 * @ return A list of results from the check . If there are no results or checking is disabled ,
 * the list is empty . */
@ Deprecated public static boolean passesAccessibilityChecksIfEnabled ( View view ) { } }

implementation: setThrowExceptionForErrors ( false ) ; List < AccessibilityViewCheckResult > results = checkViewIfCheckingEnabled ( view ) ; List < AccessibilityViewCheckResult > errors = AccessibilityCheckResultUtils . getResultsForType ( results , AccessibilityCheckResultType . ERROR ) ; return ( errors . size ( ) == 0 ) ;


signature:
public class AccessibilityUtil { /** * Specify that a specific subset of accessibility checks be run . The subsets are specified based
 * on which Robolectric version particular checks were released with . By default , all checks are
 * run { @ link ForRobolectricVersion } .
 * If you call this method , the value you pass will take precedence over any value in any
 * annotations .
 * @ param forVersion The version of checks to run for . If { @ code null } , throws away the current
 * value and falls back on the annotation or default . */
public static void setRunChecksForRobolectricVersion ( ForRobolectricVersion forVersion ) { } }

implementation: initializeValidator ( ) ; if ( forVersion != null ) { validator . setCheckPreset ( convertRoboVersionToA11yTestVersion ( forVersion ) ) ; forVersionSet = true ; } else { forVersionSet = false ; }


signature:
public class AccessibilityUtil { /** * Suppress all results that match the given matcher . Suppressed results will not be included
 * in any logs or cause any { @ code Exception } to be thrown . This capability is useful if there
 * are known issues , but checks should still look for regressions .
 * @ param matcher A matcher to match a { @ link AccessibilityViewCheckResult } . { @ code null }
 * disables suppression and is the default . */
@ SuppressWarnings ( "unchecked" ) // The generic passed to anyOf
public static void setSuppressingResultMatcher ( final Matcher < ? super AccessibilityViewCheckResult > matcher ) { } }

implementation:
initializeValidator ( ) ; /* Suppress all touch target results , since views all report size as 0x0 */
Matcher < AccessibilityCheckResult > touchTargetResultMatcher = AccessibilityCheckResultUtils . matchesChecks ( Matchers . equalTo ( TouchTargetSizeViewCheck . class ) ) ; Matcher < AccessibilityCheckResult > duplicateBoundsResultMatcher = AccessibilityCheckResultUtils . matchesChecks ( Matchers . equalTo ( DuplicateClickableBoundsViewCheck . class ) ) ; if ( matcher == null ) { validator . setSuppressingResultMatcher ( Matchers . anyOf ( touchTargetResultMatcher , duplicateBoundsResultMatcher ) ) ; } else { validator . setSuppressingResultMatcher ( Matchers . anyOf ( matcher , touchTargetResultMatcher , duplicateBoundsResultMatcher ) ) ; }


signature:
public class ShadowAccountManager { /** * The remove operation is posted to the given { @ code handler } , and will be executed according to
 * the { @ link IdleState } of the corresponding { @ link org . robolectric . util . Scheduler } . */
@ Implementation protected AccountManagerFuture < Boolean > removeAccount ( final Account account , AccountManagerCallback < Boolean > callback , Handler handler ) { } }

implementation: if ( account == null ) { throw new IllegalArgumentException ( "account is null" ) ; } return start ( new BaseRoboAccountManagerFuture < Boolean > ( callback , handler ) { @ Override public Boolean doWork ( ) throws OperationCanceledException , IOException , AuthenticatorException { return removeAccountExplicitly ( account ) ; } } ) ;


signature:
public class ShadowAccountManager { /** * Removes the account unless { @ link # setRemoveAccountIntent } has been set . If set , the future
 * Bundle will include the Intent and { @ link AccountManager # KEY _ BOOLEAN _ RESULT } will be false . */
@ Implementation ( minSdk = LOLLIPOP_MR1 ) protected AccountManagerFuture < Bundle > removeAccount ( Account account , Activity activity , AccountManagerCallback < Bundle > callback , Handler handler ) { } }

implementation: if ( account == null ) { throw new IllegalArgumentException ( "account is null" ) ; } return start ( new BaseRoboAccountManagerFuture < Bundle > ( callback , handler ) { @ Override public Bundle doWork ( ) throws OperationCanceledException , IOException , AuthenticatorException { Bundle result = new Bundle ( ) ; if ( removeAccountIntent == null ) { result . putBoolean ( AccountManager . KEY_BOOLEAN_RESULT , removeAccountExplicitly ( account ) ) ; } else { result . putBoolean ( AccountManager . KEY_BOOLEAN_RESULT , false ) ; result . putParcelable ( AccountManager . KEY_INTENT , removeAccountIntent ) ; } return result ; } } ) ;


signature:
public class ShadowAccountManager { /** * Adds an account to the AccountManager but when { @ link AccountManager # getAccountsByTypeForPackage ( String , String ) }
 * is called will be included if is in one of the # visibileToPackages
 * @ param account User account . */
public void addAccount ( Account account , String ... visibileToPackages ) { } }

implementation: addAccount ( account ) ; HashSet < String > value = new HashSet < > ( ) ; Collections . addAll ( value , visibileToPackages ) ; packageVisibileAccounts . put ( account , value ) ;


signature:
public class ShadowResourcesManager { /** * Exposes { @ link ResourcesManager # applyCompatConfigurationLocked ( int , Configuration ) } . */
public boolean callApplyConfigurationToResourcesLocked ( Configuration configuration , CompatibilityInfo compatibilityInfo ) { } }

implementation: return reflector ( _ResourcesManager_ . class , realResourcesManager ) . applyConfigurationToResourcesLocked ( configuration , compatibilityInfo ) ;


signature:
public class Util { /** * This method consumes an input stream and returns its content .
 * @ param is The input stream to read from .
 * @ return The bytes read from the stream .
 * @ throws IOException Error reading from stream . */
public static byte [ ] readBytes ( InputStream is ) throws IOException { } }

implementation: try ( ByteArrayOutputStream bos = new ByteArrayOutputStream ( is . available ( ) ) ) { copy ( is , bos ) ; return bos . toByteArray ( ) ; }


signature:
public class Util { /** * Re - throw { @ code t } ( even if it ' s a checked exception ) without requiring a { @ code throws }
 * declaration .
 * This function declares a return type of { @ link RuntimeException } but will never actually return
 * a value . This allows you to use it with a { @ code throw } statement to convince the compiler that
 * the current branch will not complete .
 * < pre > { @ code
 * throw Util . sneakyThrow ( new IOException ( ) ) ;
 * } < / pre >
 * Adapted from https : / / www . mail - archive . com / javaposse @ googlegroups . com / msg05984 . html */
@ SuppressWarnings ( "unchecked" ) public static < T extends Throwable > RuntimeException sneakyThrow ( Throwable t ) throws T { } }

implementation: throw ( T ) t ;


signature:
public class ShadowCameraManager { /** * Adds the given cameraId and characteristics to this shadow .
 * < p > The result from { @ link # getCameraIdList ( ) } will be in the order in which cameras were added .
 * @ throws IllegalArgumentException if there ' s already an existing camera with the given id . */
public void addCamera ( @ NonNull String cameraId , @ NonNull CameraCharacteristics characteristics ) { } }

implementation: Preconditions . checkNotNull ( cameraId ) ; Preconditions . checkNotNull ( characteristics ) ; Preconditions . checkArgument ( ! cameraIdToCharacteristics . containsKey ( cameraId ) ) ; cameraIdToCharacteristics . put ( cameraId , characteristics ) ;


signature:
public class ShadowCameraManager { /** * Returns what the supplied camera ' s torch is set to . */
public boolean getTorchMode ( @ NonNull String cameraId ) { } }

implementation: Preconditions . checkNotNull ( cameraId ) ; Preconditions . checkArgument ( cameraIdToCharacteristics . keySet ( ) . contains ( cameraId ) ) ; Boolean torchState = cameraTorches . get ( cameraId ) ; return torchState ;


signature:
public class NativeObjRegistry { /** * Retrieve the native id for given object . Assigns a new unique id to the object if not
 * previously registered .
 * @ deprecated Use { @ link # register ( Object ) } instead . */
@ Deprecated public synchronized long getNativeObjectId ( T o ) { } }

implementation: checkNotNull ( o ) ; Long nativeId = nativeObjToIdMap . inverse ( ) . get ( o ) ; if ( nativeId == null ) { nativeId = nextId ; if ( debug ) { System . out . printf ( "NativeObjRegistry %s: register %d -> %s%n" , name , nativeId , o ) ; } nativeObjToIdMap . put ( nativeId , o ) ; nextId ++ ; } return nativeId ;


signature:
public class NativeObjRegistry { /** * Register and assign a new unique native id for given object ( representing a C memory pointer ) .
 * @ throws IllegalStateException if the object was previously registered */
public synchronized long register ( T o ) { } }

implementation: checkNotNull ( o ) ; Long nativeId = nativeObjToIdMap . inverse ( ) . get ( o ) ; if ( nativeId != null ) { if ( debug ) { DebugInfo debugInfo = idToDebugInfoMap . get ( nativeId ) ; if ( debugInfo != null ) { System . out . printf ( "NativeObjRegistry %s: register %d -> %s already registered:%n" , name , nativeId , o ) ; debugInfo . registrationTrace . printStackTrace ( System . out ) ; } } throw new IllegalStateException ( "Object was previously registered with id " + nativeId ) ; } nativeId = nextId ; if ( debug ) { System . out . printf ( "NativeObjRegistry %s: register %d -> %s%n" , name , nativeId , o ) ; idToDebugInfoMap . put ( nativeId , new DebugInfo ( new Trace ( o ) ) ) ; } nativeObjToIdMap . put ( nativeId , o ) ; nextId ++ ; return nativeId ;


signature:
public class NativeObjRegistry { /** * Unregister an object previously registered with { @ link # register ( Object ) } .
 * @ param nativeId the unique id ( representing a C memory pointer ) of the object to unregister .
 * @ throws IllegalStateException if the object was never registered , or was previously
 * unregistered . */
public synchronized T unregister ( long nativeId ) { } }

implementation: T o = nativeObjToIdMap . remove ( nativeId ) ; if ( debug ) { System . out . printf ( "NativeObjRegistry %s: unregister %d -> %s%n" , name , nativeId , o ) ; new RuntimeException ( "unregister debug" ) . printStackTrace ( System . out ) ; } if ( o == null ) { if ( debug ) { DebugInfo debugInfo = idToDebugInfoMap . get ( nativeId ) ; debugInfo . unregistrationTraces . add ( new Trace ( o ) ) ; if ( debugInfo . unregistrationTraces . size ( ) > 1 ) { System . out . format ( "NativeObjRegistry %s: Too many unregistrations:%n" , name ) ; for ( Trace unregistration : debugInfo . unregistrationTraces ) { unregistration . printStackTrace ( System . out ) ; } } } throw new IllegalStateException ( nativeId + " has already been removed (or was never registered)" ) ; } return o ;


signature:
public class NativeObjRegistry { /** * Retrieve the native object for given id . Throws if object with that id cannot be found */
public synchronized T getNativeObject ( long nativeId ) { } }

implementation: T object = nativeObjToIdMap . get ( nativeId ) ; if ( object != null ) { return object ; } else { throw new NullPointerException ( String . format ( "Could not find object with nativeId: %d. Currently registered ids: %s" , nativeId , nativeObjToIdMap . keySet ( ) ) ) ; }


signature:
public class FragmentController { /** * Creates the activity with { @ link Bundle } and adds the fragment to the view with ID { @ code contentViewId } . */
public FragmentController < F > create ( final int contentViewId , final Bundle bundle ) { } }

implementation: shadowMainLooper . runPaused ( new Runnable ( ) { @ Override public void run ( ) { activityController . create ( bundle ) . get ( ) . getFragmentManager ( ) . beginTransaction ( ) . add ( contentViewId , fragment ) . commit ( ) ; } } ) ; return this ;


signature:
public class ShadowBitmap { /** * Returns a textual representation of the appearance of the object .
 * @ param bitmap the bitmap to visualize
 * @ return Textual representation of the appearance of the object . */
public static String visualize ( Bitmap bitmap ) { } }

implementation: ShadowBitmap shadowBitmap = Shadow . extract ( bitmap ) ; return shadowBitmap . getDescription ( ) ;


signature:
public class ShadowBitmap { /** * Note that this method will return a RuntimeException unless : - { @ code pixels } has the same
 * length as the number of pixels of the bitmap . - { @ code x = 0 } - { @ code y = 0 } - { @ code width }
 * and { @ code height } height match the current bitmap ' s dimensions . */
@ Implementation protected void getPixels ( int [ ] pixels , int offset , int stride , int x , int y , int width , int height ) { } }

implementation: if ( x != 0 || y != 0 || width != getWidth ( ) || height != getHeight ( ) || pixels . length != colors . length ) { for ( int y0 = 0 ; y0 < height ; y0 ++ ) { for ( int x0 = 0 ; x0 < width ; x0 ++ ) { pixels [ offset + y0 * stride + x0 ] = colors [ ( y0 + y ) * getWidth ( ) + x0 + x ] ; } } } else { System . arraycopy ( colors , 0 , pixels , 0 , colors . length ) ; }


signature:
public class ShadowApplication { /** * Attaches an application to a base context .
 * @ param context The context with which to initialize the application , whose base context will
 * be attached to the application */
public void callAttach ( Context context ) { } }

implementation: ReflectionHelpers . callInstanceMethod ( Application . class , realApplication , "attach" , ReflectionHelpers . ClassParameter . from ( Context . class , context ) ) ;


signature:
public class ShadowApplication { /** * Set to true if you ' d like Robolectric to strictly simulate the real Android behavior when
 * calling { @ link Context # startActivity ( android . content . Intent ) } . Real Android throws a
 * { @ link android . content . ActivityNotFoundException } if given
 * an { @ link Intent } that is not known to the { @ link android . content . pm . PackageManager }
 * By default , this behavior is off ( false ) .
 * @ param checkActivities True to validate activities . */
public void checkActivities ( boolean checkActivities ) { } }

implementation: ActivityThread activityThread = ( ActivityThread ) RuntimeEnvironment . getActivityThread ( ) ; ShadowInstrumentation shadowInstrumentation = Shadow . extract ( activityThread . getInstrumentation ( ) ) ; shadowInstrumentation . checkActivities ( checkActivities ) ;


signature:
public class ShadowConnectivityManager { /** * Counts { @ link ConnectivityManager # TYPE _ MOBILE } networks as metered . Other types will be
 * considered unmetered .
 * @ return ` true ` if the active network is metered , otherwise ` false ` .
 * @ see # setActiveNetworkInfo ( NetworkInfo )
 * @ see # setDefaultNetworkActive ( boolean ) */
@ Implementation protected boolean isActiveNetworkMetered ( ) { } }

implementation: if ( defaultNetworkActive && activeNetworkInfo != null ) { return activeNetworkInfo . getType ( ) == ConnectivityManager . TYPE_MOBILE ; } else { return false ; }


signature:
public class ShadowConnectivityManager { /** * Adds new { @ code network } to the list of all { @ link android . net . Network } s .
 * @ param network The network .
 * @ param networkInfo The network info paired with the { @ link android . net . Network } . */
public void addNetwork ( Network network , NetworkInfo networkInfo ) { } }

implementation: ShadowNetwork shadowNetwork = Shadow . extract ( network ) ; int netId = shadowNetwork . getNetId ( ) ; netIdToNetwork . put ( netId , network ) ; netIdToNetworkInfo . put ( netId , networkInfo ) ;


signature:
public class ShadowConnectivityManager { /** * Removes the { @ code network } from the list of all { @ link android . net . Network } s .
 * @ param network The network . */
public void removeNetwork ( Network network ) { } }

implementation: ShadowNetwork shadowNetwork = Shadow . extract ( network ) ; int netId = shadowNetwork . getNetId ( ) ; netIdToNetwork . remove ( netId ) ; netIdToNetworkInfo . remove ( netId ) ;


signature:
public class ShadowConnectivityManager { /** * Sets the active state of the default network .
 * By default this is true and affects the result of { @ link
 * ConnectivityManager # isActiveNetworkMetered ( ) } , { @ link
 * ConnectivityManager # isDefaultNetworkActive ( ) } , { @ link ConnectivityManager # getActiveNetwork ( ) }
 * and { @ link ConnectivityManager # getAllNetworkInfo ( ) } .
 * Calling this method with { @ code true } after any listeners have been registered with { @ link
 * ConnectivityManager # addDefaultNetworkActiveListener ( OnNetworkActiveListener ) } will result in
 * those listeners being fired .
 * @ param isActive The active state of the default network . */
public void setDefaultNetworkActive ( boolean isActive ) { } }

implementation: defaultNetworkActive = isActive ; if ( defaultNetworkActive ) { for ( ConnectivityManager . OnNetworkActiveListener l : onNetworkActiveListeners ) { if ( l != null ) { l . onNetworkActive ( ) ; } } }


signature:
public class ShadowConnectivityManager { /** * Gets the network capabilities of a given { @ link Network } .
 * @ param network The { @ link Network } object identifying the network in question .
 * @ return The { @ link android . net . NetworkCapabilities } for the network .
 * @ see # setNetworkCapabilities ( Network , NetworkCapabilities ) */
@ Implementation ( minSdk = LOLLIPOP ) protected NetworkCapabilities getNetworkCapabilities ( Network network ) { } }

implementation: return networkCapabilitiesMap . get ( network ) ;


signature:
public class Converter { /** * TODO : Handle ' anim ' resources */
public static Converter getConverter ( ResType resType ) { } }

implementation: switch ( resType ) { case ATTR_DATA : return new FromAttrData ( ) ; case BOOLEAN : return new FromBoolean ( ) ; case CHAR_SEQUENCE : return new FromCharSequence ( ) ; case COLOR : case DRAWABLE : return new FromColor ( ) ; case COLOR_STATE_LIST : case LAYOUT : return new FromFilePath ( ) ; case DIMEN : return new FromDimen ( ) ; case FILE : return new FromFile ( ) ; case FLOAT : return new FromFloat ( ) ; case INTEGER : return new FromInt ( ) ; case FRACTION : return new FromFraction ( ) ; case CHAR_SEQUENCE_ARRAY : case INTEGER_ARRAY : case TYPED_ARRAY : return new FromArray ( ) ; case STYLE : return new Converter ( ) ; default : throw new UnsupportedOperationException ( "can't convert from " + resType . name ( ) ) ; }


signature:
public class ShadowSoundPool { /** * native method . */
@ Implementation ( maxSdk = LOLLIPOP_MR1 ) protected int play ( int soundID , float leftVolume , float rightVolume , int priority , int loop , float rate ) { } }

implementation: playedSounds . add ( new Playback ( soundID , leftVolume , rightVolume , priority , loop , rate ) ) ; return 1 ;


signature:
public class ShadowSoundPool { /** * FileDescriptor which would make it difficult to check if a given sound has been placed . */
@ Implementation protected int load ( String path , int priority ) { } }

implementation: int soundId = soundIds . getAndIncrement ( ) ; idToPaths . put ( soundId , path ) ; return soundId ;


signature:
public class ShadowSoundPool { /** * Notify the { @ link OnLoadCompleteListener } , if present , that the given path was loaded . */
public void notifyPathLoaded ( String path , boolean success ) { } }

implementation: boolean soundIsKnown = false ; for ( int pathIdx = 0 ; pathIdx < idToPaths . size ( ) ; ++ pathIdx ) { if ( idToPaths . valueAt ( pathIdx ) . equals ( path ) ) { if ( listener != null ) { listener . onLoadComplete ( realObject , idToPaths . keyAt ( pathIdx ) , success ? 0 : 1 ) ; } soundIsKnown = true ; } } if ( ! soundIsKnown ) { throw new IllegalArgumentException ( "Unknown sound. You need to call load() first" ) ; }


signature:
public class ShadowSoundPool { /** * Notify the { @ link OnLoadCompleteListener } , if present , that the given resource was loaded . */
public void notifyResourceLoaded ( int resId , boolean success ) { } }

implementation: boolean soundIsKnown = false ; for ( int resIdx = 0 ; resIdx < idToRes . size ( ) ; ++ resIdx ) { if ( idToRes . valueAt ( resIdx ) == resId ) { if ( listener != null ) { listener . onLoadComplete ( realObject , idToRes . keyAt ( resIdx ) , success ? 0 : 1 ) ; } soundIsKnown = true ; } } if ( ! soundIsKnown ) { throw new IllegalArgumentException ( "Unknown sound. You need to call load() first" ) ; }


signature:
public class ShadowSoundPool { /** * Returns { @ code true } if the given path was played . */
public boolean wasPathPlayed ( String path ) { } }

implementation: for ( Playback playback : playedSounds ) { if ( idIsForPath ( playback . soundId , path ) ) { return true ; } } return false ;


signature:
public class ShadowSoundPool { /** * Returns { @ code true } if the given resource was played . */
public boolean wasResourcePlayed ( int resId ) { } }

implementation: for ( Playback playback : playedSounds ) { if ( idIsForResource ( playback . soundId , resId ) ) { return true ; } } return false ;


signature:
public class ShadowSoundPool { /** * Return a list of calls to { @ code play } made for the given path . */
public List < Playback > getPathPlaybacks ( String path ) { } }

implementation: ImmutableList . Builder < Playback > playbacks = ImmutableList . builder ( ) ; for ( Playback playback : playedSounds ) { if ( idIsForPath ( playback . soundId , path ) ) { playbacks . add ( playback ) ; } } return playbacks . build ( ) ;


signature:
public class ShadowSoundPool { /** * Return a list of calls to { @ code play } made for the given resource . */
public List < Playback > getResourcePlaybacks ( int resId ) { } }

implementation: ImmutableList . Builder < Playback > playbacks = ImmutableList . builder ( ) ; for ( Playback playback : playedSounds ) { if ( idIsForResource ( playback . soundId , resId ) ) { playbacks . add ( playback ) ; } } return playbacks . build ( ) ;


signature:
public class ShadowAppWidgetManager { /** * Simulates updating an { @ code AppWidget } with a new set of views
 * @ param appWidgetId id of widget
 * @ param views views to update */
@ Implementation protected void updateAppWidget ( int appWidgetId , RemoteViews views ) { } }

implementation: WidgetInfo widgetInfo = widgetInfos . get ( appWidgetId ) ; int layoutId = views . getLayoutId ( ) ; if ( widgetInfo . layoutId != layoutId || alwaysRecreateViewsDuringUpdate ) { widgetInfo . view = createWidgetView ( layoutId ) ; widgetInfo . layoutId = layoutId ; } widgetInfo . lastRemoteViews = views ; views . reapply ( context , widgetInfo . view ) ;


signature:
public class ShadowAppWidgetManager { /** * Triggers a reapplication of the most recent set of actions against the widget , which is what happens when the
 * phone is rotated . Does not attempt to simulate a change in screen geometry .
 * @ param appWidgetId the ID of the widget to be affected */
public void reconstructWidgetViewAsIfPhoneWasRotated ( int appWidgetId ) { } }

implementation: WidgetInfo widgetInfo = widgetInfos . get ( appWidgetId ) ; widgetInfo . view = createWidgetView ( widgetInfo . layoutId ) ; widgetInfo . lastRemoteViews . reapply ( context , widgetInfo . view ) ;


signature:
public class ShadowAppWidgetManager { /** * Creates a bunch of widgets by inflating the same layout multiple times .
 * @ param appWidgetProviderClass the app widget provider class
 * @ param widgetLayoutId id of the layout to inflate
 * @ param howManyToCreate number of new widgets to create
 * @ return the IDs of the new widgets */
public int [ ] createWidgets ( Class < ? extends AppWidgetProvider > appWidgetProviderClass , int widgetLayoutId , int howManyToCreate ) { } }

implementation: AppWidgetProvider appWidgetProvider = ReflectionHelpers . callConstructor ( appWidgetProviderClass ) ; int [ ] newWidgetIds = new int [ howManyToCreate ] ; for ( int i = 0 ; i < howManyToCreate ; i ++ ) { View widgetView = createWidgetView ( widgetLayoutId ) ; int myWidgetId = nextWidgetId ++ ; widgetInfos . put ( myWidgetId , new WidgetInfo ( widgetView , widgetLayoutId , appWidgetProvider ) ) ; newWidgetIds [ i ] = myWidgetId ; } appWidgetProvider . onUpdate ( context , realAppWidgetManager , newWidgetIds ) ; return newWidgetIds ;


signature:
public class ShadowMediaPlayer { /** * Common code path for all { @ code setDataSource ( ) } implementations .
 * < p > * Checks for any specified exceptions for the specified data source and throws them . *
 * Checks the current state and throws an exception if it is in an invalid state . * If no
 * exception is thrown in either of the previous two steps , then { @ link
 * # doSetDataSource ( DataSource ) } is called to set the data source . * Sets the player state to
 * { @ code INITIALIZED } . Usually this method would not be called directly , but indirectly through
 * one of the other { @ link # setDataSource ( String ) } implementations , which use { @ link
 * DataSource # toDataSource ( String ) } methods to convert their discrete parameters into a single
 * { @ link DataSource } instance .
 * @ param dataSource the data source that is being set .
 * @ throws IOException if the specified data source has been configured to throw an IO exception .
 * @ see # addException ( DataSource , IOException )
 * @ see # addException ( DataSource , RuntimeException )
 * @ see # doSetDataSource ( DataSource ) */
public void setDataSource ( DataSource dataSource ) throws IOException { } }

implementation: Exception e = exceptions . get ( dataSource ) ; if ( e != null ) { e . fillInStackTrace ( ) ; if ( e instanceof IOException ) { throw ( IOException ) e ; } else if ( e instanceof RuntimeException ) { throw ( RuntimeException ) e ; } throw new AssertionError ( "Invalid exception type for setDataSource: <" + e + '>' ) ; } checkStateException ( "setDataSource()" , idleState ) ; doSetDataSource ( dataSource ) ; state = INITIALIZED ;


signature:
public class ShadowMediaPlayer { /** * Sets the data source without doing any other emulation . Sets the internal data source only .
 * Calling directly can be useful for setting up a { @ link ShadowMediaPlayer } instance during
 * specific testing so that you don ' t have to clutter your tests catching exceptions you know
 * won ' t be thrown .
 * @ param dataSource the data source that is being set .
 * @ see # setDataSource ( DataSource ) */
public void doSetDataSource ( DataSource dataSource ) { } }

implementation: if ( mediaInfo . get ( dataSource ) == null ) { throw new IllegalArgumentException ( "Don't know what to do with dataSource " + dataSource + " - either add an exception with addException() or media info with addMediaInfo()" ) ; } this . dataSource = dataSource ;


signature:
public class ShadowMediaPlayer { /** * Checks states for methods that only log when there is an error . Such
 * methods throw an { @ link IllegalArgumentException } when invoked in the END
 * state , but log an error in other disallowed states . This method will either
 * emulate this behavior or else will generate an assertion if invoked from a
 * disallowed state if { @ link # setAssertOnError assertOnError } is set .
 * @ param method
 * the name of the method being tested .
 * @ param allowedStates
 * the states that this method is allowed to be called from .
 * @ see # setAssertOnError
 * @ see # checkStateError ( String , EnumSet )
 * @ see # checkStateException ( String , EnumSet ) */
private void checkStateLog ( String method , EnumSet < State > allowedStates ) { } }

implementation: switch ( invalidStateBehavior ) { case SILENT : break ; case EMULATE : if ( state == END ) { String msg = "Can't call " + method + " from state " + state ; throw new IllegalStateException ( msg ) ; } break ; case ASSERT : if ( ! allowedStates . contains ( state ) || state == END ) { String msg = "Can't call " + method + " from state " + state ; throw new AssertionError ( msg ) ; } }


signature:
public class ShadowMediaPlayer { /** * Checks states for methods that asynchronously invoke
 * { @ link android . media . MediaPlayer . OnErrorListener # onError ( MediaPlayer , int , int )
 * onError ( ) } when invoked in an illegal state . Such methods always throw
 * { @ link IllegalStateException } rather than invoke { @ code onError ( ) } if
 * they are invoked from the END state .
 * This method will either emulate this behavior by posting an
 * { @ code onError ( ) } callback to the current thread ' s message queue ( or
 * throw an { @ link IllegalStateException } if invoked from the END state ) , or
 * else it will generate an assertion if { @ link # setAssertOnError
 * assertOnError } is set .
 * @ param method
 * the name of the method being tested .
 * @ param allowedStates
 * the states that this method is allowed to be called from .
 * @ see # getHandler
 * @ see # setAssertOnError
 * @ see # checkStateLog ( String , EnumSet )
 * @ see # checkStateException ( String , EnumSet ) */
private boolean checkStateError ( String method , EnumSet < State > allowedStates ) { } }

implementation: if ( ! allowedStates . contains ( state ) ) { switch ( invalidStateBehavior ) { case SILENT : break ; case EMULATE : if ( state == END ) { String msg = "Can't call " + method + " from state " + state ; throw new IllegalStateException ( msg ) ; } state = ERROR ; postEvent ( invalidStateErrorCallback ) ; return false ; case ASSERT : String msg = "Can't call " + method + " from state " + state ; throw new AssertionError ( msg ) ; } } return true ;


signature:
public class ShadowMediaPlayer { /** * Checks states for methods that synchronously throw an exception when
 * invoked in an illegal state . This method will likewise throw an
 * { @ link IllegalArgumentException } if it determines that the method has been
 * invoked from a disallowed state , or else it will generate an assertion if
 * { @ link # setAssertOnError assertOnError } is set .
 * @ param method
 * the name of the method being tested .
 * @ param allowedStates
 * the states that this method is allowed to be called from .
 * @ see # setAssertOnError
 * @ see # checkStateLog ( String , EnumSet )
 * @ see # checkStateError ( String , EnumSet ) */
private void checkStateException ( String method , EnumSet < State > allowedStates ) { } }

implementation: if ( ! allowedStates . contains ( state ) ) { String msg = "Can't call " + method + " from state " + state ; switch ( invalidStateBehavior ) { case SILENT : break ; case EMULATE : throw new IllegalStateException ( msg ) ; case ASSERT : throw new AssertionError ( msg ) ; } }


signature:
public class ShadowMediaPlayer { /** * Simulates { @ link MediaPlayer # prepareAsync ( ) } . Sleeps for { @ link MediaInfo # getPreparationDelay ( )
 * preparationDelay } ms by calling { @ link SystemClock # sleep ( long ) } before calling { @ link
 * # invokePreparedListener ( ) } .
 * < p > If { @ code preparationDelay } is not positive and non - zero , there is no sleep .
 * @ see MediaInfo # setPreparationDelay ( int )
 * @ see # invokePreparedListener ( ) */
@ Implementation protected void prepare ( ) { } }

implementation: checkStateException ( "prepare()" , preparableStates ) ; MediaInfo info = getMediaInfo ( ) ; if ( info . preparationDelay > 0 ) { SystemClock . sleep ( info . preparationDelay ) ; } invokePreparedListener ( ) ;


signature:
public class ShadowMediaPlayer { /** * Simulates { @ link MediaPlayer # prepareAsync ( ) } . Sets state to PREPARING and posts a callback to
 * { @ link # invokePreparedListener ( ) } if the current preparation delay for the current media ( see
 * { @ link # getMediaInfo ( ) } ) is & gt ; = 0 , otherwise the test suite is responsible for calling { @ link
 * # invokePreparedListener ( ) } directly if required .
 * @ see MediaInfo # setPreparationDelay ( int )
 * @ see # invokePreparedListener ( ) */
@ Implementation protected void prepareAsync ( ) { } }

implementation: checkStateException ( "prepareAsync()" , preparableStates ) ; state = PREPARING ; MediaInfo info = getMediaInfo ( ) ; if ( info . preparationDelay >= 0 ) { postEventDelayed ( preparedCallback , info . preparationDelay ) ; }


signature:
public class ShadowMediaPlayer { /** * Simulates private native method { @ link MediaPlayer # _ start ( ) } . Sets state to STARTED and calls
 * { @ link # doStart ( ) } to start scheduling playback callback events .
 * < p > If the current state is PLAYBACK _ COMPLETED , the current position is reset to zero before
 * starting playback .
 * @ see # doStart ( ) */
@ Implementation protected void start ( ) { } }

implementation: if ( checkStateError ( "start()" , startableStates ) ) { if ( state == PLAYBACK_COMPLETED ) { startOffset = 0 ; } state = STARTED ; doStart ( ) ; }


signature:
public class ShadowMediaPlayer { /** * Pauses simulated playback . After this method is called , the player is no
 * longer " really playing " ( see { @ link # isReallyPlaying } for a definition of
 * " really playing " ) .
 * This method is used internally by the various shadow method implementations
 * of the MediaPlayer public API , but may also be called directly by the test
 * suite if you wish to simulate an internal pause .
 * @ see # isReallyPlaying ( )
 * @ see # doStart ( ) */
public void doStop ( ) { } }

implementation: startOffset = getCurrentPositionRaw ( ) ; if ( nextPlaybackEvent != null ) { handler . removeMessages ( MEDIA_EVENT ) ; nextPlaybackEvent = null ; } startTime = - 1 ;


signature:
public class ShadowMediaPlayer { /** * Simulates call to { @ link MediaPlayer # _ release ( ) } . Calls { @ link # doStop ( ) } to suspend playback
 * event callbacks and sets the state to END . */
@ Implementation protected void _release ( ) { } }

implementation: checkStateException ( "release()" , allStates ) ; doStop ( ) ; state = END ; handler . removeMessages ( MEDIA_EVENT ) ;


signature:
public class ShadowMediaPlayer { /** * Simulates call to { @ link MediaPlayer # _ reset ( ) } . Calls { @ link # doStop ( ) } to suspend playback
 * event callbacks and sets the state to IDLE . */
@ Implementation protected void _reset ( ) { } }

implementation: checkStateException ( "reset()" , nonEndStates ) ; doStop ( ) ; state = IDLE ; handler . removeMessages ( MEDIA_EVENT ) ; startOffset = 0 ;


signature:
public class ShadowMediaPlayer { /** * Allows test cases to simulate seek completion by invoking callback . */
public void invokeSeekCompleteListener ( ) { } }

implementation: int duration = getMediaInfo ( ) . duration ; setCurrentPosition ( pendingSeek > duration ? duration : pendingSeek < 0 ? 0 : pendingSeek ) ; pendingSeek = - 1 ; if ( state == STARTED ) { doStart ( ) ; } if ( seekCompleteListener == null ) { return ; } seekCompleteListener . onSeekComplete ( player ) ;


signature:
public class ShadowMediaPlayer { /** * Allows test cases to directly simulate invocation of the OnInfo event .
 * @ param what
 * parameter to pass in to { @ code what } in
 * { @ link MediaPlayer . OnInfoListener # onInfo ( MediaPlayer , int , int ) } .
 * @ param extra
 * parameter to pass in to { @ code extra } in
 * { @ link MediaPlayer . OnInfoListener # onInfo ( MediaPlayer , int , int ) } . */
public void invokeInfoListener ( int what , int extra ) { } }

implementation: if ( infoListener != null ) { infoListener . onInfo ( player , what , extra ) ; }


signature:
public class ShadowMediaPlayer { /** * Allows test cases to directly simulate invocation of the OnError event .
 * @ param what
 * parameter to pass in to { @ code what } in
 * { @ link MediaPlayer . OnErrorListener # onError ( MediaPlayer , int , int ) } .
 * @ param extra
 * parameter to pass in to { @ code extra } in
 * { @ link MediaPlayer . OnErrorListener # onError ( MediaPlayer , int , int ) } . */
public void invokeErrorListener ( int what , int extra ) { } }

implementation:
// Calling doStop ( ) un - schedules the next event and
// stops normal event flow from continuing .
doStop ( ) ; state = ERROR ; boolean handled = errorListener != null && errorListener . onError ( player , what , extra ) ; if ( ! handled ) { // The documentation isn ' t very clear if onCompletion is
// supposed to be called from non - playing states
// ( ie , states other than STARTED or PAUSED ) . Testing
// revealed that onCompletion is invoked even if playback
// hasn ' t started or is not in progress .
invokeCompletionListener ( ) ; // Need to set this again because
// invokeCompletionListener ( ) will set the state
// to PLAYBACK _ COMPLETED
state = ERROR ; }


signature:
public class BaseCursor { /** * Mimics ContentResolver . query ( Uri uri , String [ ] projection , String selection , String [ ] selectionArgs , String sortOrder ) */
public void setQuery ( Uri uri , String [ ] projection , String selection , String [ ] selectionArgs , String sortOrder ) { } }

implementation: // Override this in your subclass if you care to implement any of the other methods based on the query that was performed .


signature:
public class ShadowDisplay { /** * Returns the default display .
 * @ return the default display */
public static Display getDefaultDisplay ( ) { } }

implementation: WindowManager windowManager = ( WindowManager ) RuntimeEnvironment . application . getSystemService ( Context . WINDOW_SERVICE ) ; return windowManager . getDefaultDisplay ( ) ;


signature:
public class ShadowDisplay { /** * If { @ link # setScaledDensity ( float ) } has been called , { @ link DisplayMetrics # scaledDensity } will
 * be modified to reflect the value specified . Note that this is not a realistic state .
 * @ deprecated This behavior is deprecated and will be removed in Robolectric 3.7. */
@ Deprecated @ Implementation protected void getMetrics ( DisplayMetrics outMetrics ) { } }

implementation: if ( isJB ( ) ) { outMetrics . density = densityDpi * DisplayMetrics . DENSITY_DEFAULT_SCALE ; outMetrics . densityDpi = densityDpi ; outMetrics . scaledDensity = scaledDensity ; outMetrics . widthPixels = width ; outMetrics . heightPixels = height ; outMetrics . xdpi = xdpi ; outMetrics . ydpi = ydpi ; } else { directlyOn ( realObject , Display . class ) . getMetrics ( outMetrics ) ; if ( scaledDensity != null ) { outMetrics . scaledDensity = scaledDensity ; } }


signature:
public class ShadowDisplay { /** * If { @ link # setScaledDensity ( float ) } has been called , { @ link DisplayMetrics # scaledDensity } will
 * be modified to reflect the value specified . Note that this is not a realistic state .
 * @ deprecated This behavior is deprecated and will be removed in Robolectric 3.7. */
@ Deprecated @ Implementation protected void getRealMetrics ( DisplayMetrics outMetrics ) { } }

implementation: if ( isJB ( ) ) { getMetrics ( outMetrics ) ; outMetrics . widthPixels = realWidth ; outMetrics . heightPixels = realHeight ; } else { directlyOn ( realObject , Display . class ) . getRealMetrics ( outMetrics ) ; if ( scaledDensity != null ) { outMetrics . scaledDensity = scaledDensity ; } }


signature:
public class ShadowDisplay { /** * If { @ link # setDisplayId ( int ) } has been called , this method will return the specified value .
 * @ deprecated This behavior is deprecated and will be removed in Robolectric 3.7. */
@ Deprecated @ Implementation protected int getDisplayId ( ) { } }

implementation: return displayId == null ? directlyOn ( realObject , Display . class ) . getDisplayId ( ) : displayId ;


signature:
public class ShadowDisplay { /** * If { @ link # setRefreshRate ( float ) } has been called , this method will return the specified value .
 * @ deprecated This behavior is deprecated and will be removed in Robolectric 3.7. */
@ Deprecated @ Implementation protected float getRefreshRate ( ) { } }

implementation:
if ( refreshRate != null ) { return refreshRate ; } float realRefreshRate = directlyOn ( realObject , Display . class ) . getRefreshRate ( ) ; // refresh rate may be set by native code . if its 0 , set to 60fps
if ( realRefreshRate < 0.1 ) { realRefreshRate = 60 ; } return realRefreshRate ;


signature:
public class ShadowDisplay { /** * If { @ link # setPixelFormat ( int ) } has been called , this method will return the specified value .
 * @ deprecated This behavior is deprecated and will be removed in Robolectric 3.7. */
@ Deprecated @ Implementation protected int getPixelFormat ( ) { } }

implementation: return pixelFormat == null ? directlyOn ( realObject , Display . class ) . getPixelFormat ( ) : pixelFormat ;


signature:
public class ShadowDisplay { /** * Changes the density for this display .
 * Any registered { @ link android . hardware . display . DisplayManager . DisplayListener } s will be
 * notified of the change . */
public void setDensityDpi ( int densityDpi ) { } }

implementation: if ( isJB ( ) ) { this . densityDpi = densityDpi ; } else { ShadowDisplayManager . changeDisplay ( realObject . getDisplayId ( ) , di -> di . logicalDensityDpi = densityDpi ) ; }


signature:
public class ShadowDisplay { /** * Changes the horizontal DPI for this display .
 * Any registered { @ link android . hardware . display . DisplayManager . DisplayListener } s will be
 * notified of the change . */
public void setXdpi ( float xdpi ) { } }

implementation: if ( isJB ( ) ) { this . xdpi = xdpi ; } else { ShadowDisplayManager . changeDisplay ( realObject . getDisplayId ( ) , di -> di . physicalXDpi = xdpi ) ; }


signature:
public class ShadowDisplay { /** * Changes the vertical DPI for this display .
 * Any registered { @ link android . hardware . display . DisplayManager . DisplayListener } s will be
 * notified of the change . */
public void setYdpi ( float ydpi ) { } }

implementation: if ( isJB ( ) ) { this . ydpi = ydpi ; } else { ShadowDisplayManager . changeDisplay ( realObject . getDisplayId ( ) , di -> di . physicalYDpi = ydpi ) ; }


signature:
public class ShadowDisplay { /** * Changes the name for this display .
 * Any registered { @ link android . hardware . display . DisplayManager . DisplayListener } s will be
 * notified of the change . */
public void setName ( String name ) { } }

implementation: if ( isJB ( ) ) { this . name = name ; } else { ShadowDisplayManager . changeDisplay ( realObject . getDisplayId ( ) , di -> di . name = name ) ; }


signature:
public class ShadowDisplay { /** * Changes the flags for this display .
 * Any registered { @ link android . hardware . display . DisplayManager . DisplayListener } s will be
 * notified of the change . */
public void setFlags ( int flags ) { } }

implementation: reflector ( _Display_ . class , realObject ) . setFlags ( flags ) ; if ( ! isJB ( ) ) { ShadowDisplayManager . changeDisplay ( realObject . getDisplayId ( ) , di -> di . flags = flags ) ; }


signature:
public class ShadowDisplay { /** * Changes the width available to the application for this display .
 * Any registered { @ link android . hardware . display . DisplayManager . DisplayListener } s will be
 * notified of the change .
 * @ param width the new width in pixels */
public void setWidth ( int width ) { } }

implementation: if ( isJB ( ) ) { this . width = width ; } else { ShadowDisplayManager . changeDisplay ( realObject . getDisplayId ( ) , di -> di . appWidth = width ) ; }


signature:
public class ShadowDisplay { /** * Changes the height available to the application for this display .
 * Any registered { @ link android . hardware . display . DisplayManager . DisplayListener } s will be
 * notified of the change .
 * @ param height new height in pixels */
public void setHeight ( int height ) { } }

implementation: if ( isJB ( ) ) { this . height = height ; } else { ShadowDisplayManager . changeDisplay ( realObject . getDisplayId ( ) , di -> di . appHeight = height ) ; }


signature:
public class ShadowDisplay { /** * Changes the simulated physical width for this display .
 * Any registered { @ link android . hardware . display . DisplayManager . DisplayListener } s will be
 * notified of the change .
 * @ param width the new width in pixels */
public void setRealWidth ( int width ) { } }

implementation: if ( isJB ( ) ) { this . realWidth = width ; } else { ShadowDisplayManager . changeDisplay ( realObject . getDisplayId ( ) , di -> di . logicalWidth = width ) ; }


signature:
public class ShadowDisplay { /** * Changes the simulated physical height for this display .
 * Any registered { @ link android . hardware . display . DisplayManager . DisplayListener } s will be
 * notified of the change .
 * @ param height the new height in pixels */
public void setRealHeight ( int height ) { } }

implementation: if ( isJB ( ) ) { this . realHeight = height ; } else { ShadowDisplayManager . changeDisplay ( realObject . getDisplayId ( ) , di -> di . logicalHeight = height ) ; }


signature:
public class ShadowDisplay { /** * Changes the rotation for this display .
 * Any registered { @ link android . hardware . display . DisplayManager . DisplayListener } s will be
 * notified of the change .
 * @ param rotation one of { @ link Surface # ROTATION _ 0 } , { @ link Surface # ROTATION _ 90 } ,
 * { @ link Surface # ROTATION _ 180 } , { @ link Surface # ROTATION _ 270} */
public void setRotation ( int rotation ) { } }

implementation: if ( isJB ( ) ) { this . rotation = rotation ; } else { ShadowDisplayManager . changeDisplay ( realObject . getDisplayId ( ) , di -> di . rotation = rotation ) ; }


signature:
public class ShadowDisplay { /** * Changes the simulated state for this display , such as whether it is on or off
 * Any registered { @ link android . hardware . display . DisplayManager . DisplayListener } s will be
 * notified of the change .
 * @ param state the new state : one of { @ link Display # STATE _ OFF } , { @ link Display # STATE _ ON } ,
 * { @ link Display # STATE _ DOZE } , { @ link Display # STATE _ DOZE _ SUSPEND } , or
 * { @ link Display # STATE _ UNKNOWN } . */
public void setState ( int state ) { } }

implementation: if ( ! isJB ( ) ) { ShadowDisplayManager . changeDisplay ( realObject . getDisplayId ( ) , di -> di . state = state ) ; }