Lazarus

Programming => Operating Systems => Android => Topic started by: Mongkey on August 19, 2021, 12:58:28 pm

Title: LAMW (solved) how to prevent location mocking / fake gps on LAMW
Post by: Mongkey on August 19, 2021, 12:58:28 pm
This is java article i've got, i knew it depreciated on API >25, but it very interesting.

https://www.programcreek.com/java-api-examples/?class=android.telephony.TelephonyManager&method=getAllCellInfo

Since i am very beginner on java, i cant implement it, because the return value like tstring.
Title: Re: LAMW how to add function on jtelephony.java -> getAllCellInfo()?
Post by: engkin on August 19, 2021, 04:00:59 pm
I think this is a Pascal problem. Any Java object is simply translated as a pointer:
Code: Pascal  [Select][+][-]
  1. unit And_jni;
  2. ...
  3. type
  4. ....
  5.      jobject=pointer;

including jList.

While, up to this point, it might be eaiser to solve problems on the Java side, I believe the proper way is to move the problem to the Pascal side.
Title: Re: LAMW how to add function on jtelephony.java -> getAllCellInfo()?
Post by: engkin on August 19, 2021, 04:05:44 pm
For instance android.telephony.TelephonyManager is something like:
Code: Pascal  [Select][+][-]
  1. unit uATTelephonyManager;
  2.  
  3. {$mode delphi}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, And_jni, AndroidWidget,
  9.   Laz_And_Controls, uAndroidCommon;
  10.  
  11. type
  12.  
  13.   { jTelephonyManager }
  14.  
  15.   jTelephonyManager=class(jCommon)
  16.   protected
  17.     const CClassPath:string='android/telephony/TelephonyManager';
  18.   protected
  19.     {Shared by *all* jTelephonyManager instances}
  20.     FjClass:jObject;static;
  21.     FInitialized:boolean;static;
  22.     //MethodId fields
  23.     jMethodId_getPhoneCount:jmethodID;static;
  24.     jMethodId_createForSubscriptionId:jmethodID;static;
  25.     jMethodId_getDeviceSoftwareVersion:jmethodID;static;
  26.     jMethodId_getDeviceId1:jmethodID;static;
  27.     jMethodId_getDeviceId2:jmethodID;static;
  28.     jMethodId_getCellLocation:jmethodID;static;
  29.     jMethodId_getNeighboringCellInfo:jmethodID;static;
  30.     jMethodId_getPhoneType:jmethodID;static;
  31.     jMethodId_getNetworkOperatorName:jmethodID;static;
  32.     jMethodId_getNetworkOperator:jmethodID;static;
  33.     jMethodId_isNetworkRoaming:jmethodID;static;
  34.     jMethodId_getNetworkCountryIso:jmethodID;static;
  35.     jMethodId_getNetworkType:jmethodID;static;
  36.     jMethodId_getDataNetworkType:jmethodID;static;
  37.     jMethodId_getVoiceNetworkType:jmethodID;static;
  38.     jMethodId_hasIccCard:jmethodID;static;
  39.     jMethodId_getSimState:jmethodID;static;
  40.     jMethodId_getSimOperator:jmethodID;static;
  41.     jMethodId_getSimOperatorName:jmethodID;static;
  42.     jMethodId_getSimCountryIso:jmethodID;static;
  43.     jMethodId_getSimSerialNumber:jmethodID;static;
  44.     jMethodId_getSubscriberId:jmethodID;static;
  45.     jMethodId_getGroupIdLevel1:jmethodID;static;
  46.     jMethodId_getLine1Number:jmethodID;static;
  47.     jMethodId_setLine1NumberForDisplay:jmethodID;static;
  48.     jMethodId_getVoiceMailNumber:jmethodID;static;
  49.     jMethodId_setVoiceMailNumber:jmethodID;static;
  50.     jMethodId_getVoiceMailAlphaTag:jmethodID;static;
  51.     jMethodId_getCallState:jmethodID;static;
  52.     jMethodId_getDataActivity:jmethodID;static;
  53.     jMethodId_getDataState:jmethodID;static;
  54.     jMethodId_listen:jmethodID;static;
  55.     jMethodId_isVoiceCapable:jmethodID;static;
  56.     jMethodId_isSmsCapable:jmethodID;static;
  57.     jMethodId_getAllCellInfo:jmethodID;static;
  58.     jMethodId_getMmsUserAgent:jmethodID;static;
  59.     jMethodId_getMmsUAProfUrl:jmethodID;static;
  60.     jMethodId_iccOpenLogicalChannel:jmethodID;static;
  61.     jMethodId_iccCloseLogicalChannel:jmethodID;static;
  62.     jMethodId_iccTransmitApduLogicalChannel:jmethodID;static;
  63.     jMethodId_iccTransmitApduBasicChannel:jmethodID;static;
  64.     jMethodId_iccExchangeSimIO:jmethodID;static;
  65.     jMethodId_sendEnvelopeWithStatus:jmethodID;static;
  66.     jMethodId_getIccAuthentication:jmethodID;static;
  67.     jMethodId_setPreferredNetworkTypeToGlobal:jmethodID;static;
  68.     jMethodId_hasCarrierPrivileges:jmethodID;static;
  69.     jMethodId_setOperatorBrandOverride:jmethodID;static;
  70.     jMethodId_canChangeDtmfToneLength:jmethodID;static;
  71.     jMethodId_isWorldPhone:jmethodID;static;
  72.     jMethodId_isTtyModeSupported:jmethodID;static;
  73.     jMethodId_isHearingAidCompatibilitySupported:jmethodID;static;
  74.     jMethodId_getVoicemailRingtoneUri:jmethodID;static;
  75.     jMethodId_isVoicemailVibrationEnabled:jmethodID;static;
  76.   protected
  77.     class function get_jClass:jobject;override;
  78.     class procedure get_jIDs;override;
  79.   public
  80.     constructor Create(AjObject:jObject=nil);overload;
  81.     class procedure Init;
  82.   public
  83.     //Procs
  84.     function getPhoneCount:jint;
  85.     function createForSubscriptionId(_subId:jint):jobject;
  86.     function getDeviceSoftwareVersion:String;
  87.     function getDeviceId:String;overload;
  88.     function getDeviceId(_slotId:jint):String;overload;
  89.     function getCellLocation:jobject;
  90.     function getNeighboringCellInfo:jobject;
  91.     function getPhoneType:jint;
  92.     function getNetworkOperatorName:String;
  93.     function getNetworkOperator:String;
  94.     function isNetworkRoaming:boolean;
  95.     function getNetworkCountryIso:String;
  96.     function getNetworkType:jint;
  97.     function getDataNetworkType:jint;
  98.     function getVoiceNetworkType:jint;
  99.     function hasIccCard:boolean;
  100.     function getSimState:jint;
  101.     function getSimOperator:String;
  102.     function getSimOperatorName:String;
  103.     function getSimCountryIso:String;
  104.     function getSimSerialNumber:String;
  105.     function getSubscriberId:String;
  106.     function getGroupIdLevel1:String;
  107.     function getLine1Number:String;
  108.     function setLine1NumberForDisplay(_alphaTag:String;_number:String):boolean;
  109.     function getVoiceMailNumber:String;
  110.     function setVoiceMailNumber(_alphaTag:String;_number:String):boolean;
  111.     function getVoiceMailAlphaTag:String;
  112.     function getCallState:jint;
  113.     function getDataActivity:jint;
  114.     function getDataState:jint;
  115.     procedure listen(_listener:jobject;_events:jint);
  116.     function isVoiceCapable:boolean;
  117.     function isSmsCapable:boolean;
  118.     function getAllCellInfo:jobject;
  119.     function getMmsUserAgent:String;
  120.     function getMmsUAProfUrl:String;
  121.     function iccOpenLogicalChannel(_AID:String):jobject;
  122.     function iccCloseLogicalChannel(_channel:jint):boolean;
  123.     function iccTransmitApduLogicalChannel(_channel:jint;_cla:jint;_instruction:jint;_p1:jint;_p2:jint;_p3:jint;_data:String):String;
  124.     function iccTransmitApduBasicChannel(_cla:jint;_instruction:jint;_p1:jint;_p2:jint;_p3:jint;_data:String):String;
  125.     function iccExchangeSimIO(_fileID:jint;_command:jint;_p1:jint;_p2:jint;_p3:jint;_filePath:String):jbyte;
  126.     function sendEnvelopeWithStatus(_content:String):String;
  127.     function getIccAuthentication(_appType:jint;_authType:jint;_data:String):String;
  128.     function setPreferredNetworkTypeToGlobal:boolean;
  129.     function hasCarrierPrivileges:boolean;
  130.     function setOperatorBrandOverride(_brand:String):boolean;
  131.     function canChangeDtmfToneLength:boolean;
  132.     function isWorldPhone:boolean;
  133.     function isTtyModeSupported:boolean;
  134.     function isHearingAidCompatibilitySupported:boolean;
  135.     function getVoicemailRingtoneUri(_accountHandle:jobject):jobject;
  136.     function isVoicemailVibrationEnabled(_accountHandle:jobject):boolean;
  137.   end;
  138.  
  139. implementation
  140.  
  141. { jTelephonyManager }
  142.  
  143. constructor jTelephonyManager.Create(AjObject:jObject);
  144. begin
  145.   inherited Create(AjObject);
  146. end;
  147.  
  148. ...
  149. //code was removed to please the forum post limit :(
  150.  

This code is machine generated. For now, it ignores exceptions which should be fixed.

You are interested in:
Code: Pascal  [Select][+][-]
  1.     function getAllCellInfo:jobject;

Notice how it returns jobject. Now we need another class for java.util.List:
Code: Pascal  [Select][+][-]
  1. unit uJUList;
  2.  
  3. {$mode delphi}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, And_jni, AndroidWidget,
  9.   Laz_And_Controls, uAndroidCommon;
  10.  
  11. type
  12.  
  13.   { jList }
  14.  
  15.   jList=class(jCommon)
  16.   protected
  17.     const CClassPath:string='java/util/List';
  18.   protected
  19.     {Shared by *all* jList instances}
  20.     FjClass:jObject;static;
  21.     FInitialized:boolean;static;
  22.     //MethodId fields
  23.     jMethodId_size:jmethodID;static;
  24.     jMethodId_isEmpty:jmethodID;static;
  25.     jMethodId_contains:jmethodID;static;
  26.     jMethodId_toArray1:jmethodID;static;
  27.     jMethodId_toArray2:jmethodID;static;
  28.     jMethodId_remove:jmethodID;static;
  29.     jMethodId_addAll:jmethodID;static;
  30.     jMethodId_removeAll:jmethodID;static;
  31.     jMethodId_clear:jmethodID;static;
  32.     jMethodId_equals:jmethodID;static;
  33.     jMethodId_get:jmethodID;static;
  34.     jMethodId_add:jmethodID;static;
  35.     jMethodId_indexOf:jmethodID;static;
  36.     jMethodId_listIterator1:jmethodID;static;
  37.     jMethodId_listIterator2:jmethodID;static;
  38.   protected
  39.     class function get_jClass:jobject;override;
  40.     class procedure get_jIDs;override;
  41.   public
  42.     constructor Create(AjObject:jObject=nil);overload;
  43.     class procedure Init;
  44.   public
  45.     //Procs
  46.     function size:jint;
  47.     function isEmpty:boolean;
  48.     function contains(__Param1:jobject):boolean;
  49.     function toArray:jobject;overload;
  50.     function toArray(__Param2:jobject):jobject;overload;
  51.     function remove(__Param1:jobject):boolean;
  52.     function addAll(__Param1:jobject):boolean;
  53.     function removeAll(__Param1:jobject):boolean;
  54.     procedure clear;
  55.     function equals(__Param1:jobject):boolean;
  56.     function get(__Param1:jint):jobject;
  57.     procedure add(__Param1:jint;__Param2:jobject);
  58.     function indexOf(__Param1:jobject):jint;
  59.     function listIterator:jobject;overload;
  60.     function listIterator(__Param1:jint):jobject;overload;
  61.   end;
  62.  
  63. implementation
  64.  
  65. { jList }
  66.  
  67. constructor jList.Create(AjObject:jObject);
  68. begin
  69.   inherited Create(AjObject);
  70. end;
  71. ...
  72. //code is cut to please the forum editor
  73.  

Just like the previous code, this was machine generated.

In theory, you take the jobject from getAllCellInfo and pass it to jList.Create

jList should give you access to its items which are of type CellInfo, so we need a third class:
Code: Pascal  [Select][+][-]
  1. unit uATCellInfo;
  2.  
  3. {$mode delphi}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, And_jni, AndroidWidget,
  9.   Laz_And_Controls, uAndroidCommon;
  10.  
  11. type
  12.  
  13.   { jCellInfo }
  14.  
  15.   jCellInfo=class(jCommon)
  16.   protected
  17.     const CClassPath:string='android/telephony/CellInfo';
  18.   protected
  19.     {Shared by *all* jCellInfo instances}
  20.     FjClass:jObject;static;
  21.     FInitialized:boolean;static;
  22.     //MethodId fields
  23.     jMethodId_isRegistered:jmethodID;static;
  24.     jMethodId_getTimeStamp:jmethodID;static;
  25.     jMethodId_hashCode:jmethodID;static;
  26.     jMethodId_equals:jmethodID;static;
  27.     jMethodId_toString:jmethodID;static;
  28.     jMethodId_describeContents:jmethodID;static;
  29.     jMethodId_writeToParcel:jmethodID;static;
  30.   protected
  31.     class function get_jClass:jobject;override;
  32.     class procedure get_jIDs;override;
  33.   public
  34.     constructor Create(AjObject:jObject=nil);overload;
  35.     class procedure Init;
  36.   public
  37.     //Procs
  38.     function isRegistered:boolean;
  39.     function getTimeStamp:jlong;
  40.     function hashCode:jint;
  41.     function equals(_other:jobject):boolean;
  42.     function toString:String;
  43.     function describeContents:jint;
  44.     procedure writeToParcel(__Param1:jobject;__Param2:jint);
  45.   end;
  46.  
  47. implementation
  48.  
  49. { jCellInfo }
  50.  
  51. constructor jCellInfo.Create(AjObject:jObject);
  52. begin
  53.   inherited Create(AjObject);
  54. end;
  55.  
  56. class procedure jCellInfo.Init;
  57. var
  58.   LjClass:jobject;
  59. begin
  60.   if not FInitialized then
  61.   begin
  62.     LjClass:=Get_jClassLocalRef(CClassPath);
  63.     FjClass:=Get_jObjGlobalRef(LjClass);
  64.     Delete_jLocalRef(LjClass);
  65.     get_jIDs;
  66.     FInitialized:=True;
  67.   end;
  68. end;
  69.  
  70. class function jCellInfo.get_jClass:jobject;
  71. begin
  72.   Result:=FjClass;
  73. end;
  74.  
  75. class procedure jCellInfo.get_jIDs;
  76. begin
  77.   jMethodId_isRegistered:=Get_jMethodID(FjClass,'isRegistered','()Z');
  78.   jMethodId_getTimeStamp:=Get_jMethodID(FjClass,'getTimeStamp','()J');
  79.   jMethodId_hashCode:=Get_jMethodID(FjClass,'hashCode','()I');
  80.   jMethodId_equals:=Get_jMethodID(FjClass,'equals','(Ljava/lang/Object;)Z');
  81.   jMethodId_toString:=Get_jMethodID(FjClass,'toString','()Ljava/lang/String;');
  82.   jMethodId_describeContents:=Get_jMethodID(FjClass,'describeContents','()I');
  83.   jMethodId_writeToParcel:=Get_jMethodID(FjClass,'writeToParcel','(Landroid/os/Parcel;I)V');
  84. end;
  85.  
  86. function jCellInfo.isRegistered:boolean;
  87. begin
  88. // ()Z
  89.   Result:=jmethod_get_boolean(jMethodID_isRegistered);
  90. end;
  91.  
  92. function jCellInfo.getTimeStamp:jlong;
  93. begin
  94. // ()J
  95.   Result:=jmethod_get_jlong(jMethodID_getTimeStamp);
  96. end;
  97.  
  98. function jCellInfo.hashCode:jint;
  99. begin
  100. // ()I
  101.   Result:=jmethod_get_jint(jMethodID_hashCode);
  102. end;
  103.  
  104. function jCellInfo.equals(_other:jobject):boolean;
  105. var
  106.   jParams:array[0..0] of jvalue absolute _other;
  107. begin
  108. // (Ljava/lang/Object;)Z
  109.   Result:=jmethod_get_booleanA(jMethodId_equals,jParams);
  110. end;
  111.  
  112. function jCellInfo.toString:String;
  113. begin
  114. // ()Ljava/lang/String;
  115.   Result:=jmethod_get_String(jMethodID_toString);
  116. end;
  117.  
  118. function jCellInfo.describeContents:jint;
  119. begin
  120. // ()I
  121.   Result:=jmethod_get_jint(jMethodID_describeContents);
  122. end;
  123.  
  124. procedure jCellInfo.writeToParcel(__Param1:jobject;__Param2:jint);
  125. var
  126.   jParams:array[0..1] of jvalue;
  127. begin
  128. // (Landroid/os/Parcel;I)V
  129.   jParams[0].l:=__Param1;
  130.   jParams[1].i:=__Param2;
  131.   jmethod_voidA(jMethodId_writeToParcel,jParams);
  132. end;
  133.  
  134. end.
  135.  

It might be possible to use Pascal generics to make jList more like its counterpart in Java.

Anyway, I could be wrong, but this is how I see it.

WARNING:
This code was not tested.
Title: Re: LAMW how to add function on jtelephony.java -> getAllCellInfo()?
Post by: Mongkey on August 20, 2021, 12:05:23 am
 Thank you bro! I'll do my best to follow your sample.
Title: Re: LAMW how to add function on jtelephony.java -> getAllCellInfo()?
Post by: Mongkey on August 20, 2021, 01:34:57 am
i tried a lot, too much errors, not find symbol ,i dont understand java, its difficult for me  %),

I wish this attached code functions intact to LAMW jTelephony component, or new component jGeoFencing  :D

I got many fake gps coordinates, may be by retrieving from cell LAC, MNC solving this problem.

New candidate -> geofencing sample.

Thank you anyway!
Title: Re: LAMW how to add function on jtelephony.java -> getAllCellInfo()?
Post by: jmpessoa on August 20, 2021, 06:51:20 am
Done!

improved jTelephonyManager component

[need tests  and maybe some fix....]

[need "android.permission.ACCESS_COARSE_LOCATION"  granted by the user! ]

 GetLocationAreaCode()
 GetBaseStationId()
 GetMobileNetworkCode()
GetMobileCountryCode()

Thanks you!

PS. files changed:

"jTelephonyManager.java"
"telephonymanager.pas"
Title: Re: LAMW how to add function on jtelephony.java -> getAllCellInfo()?
Post by: Mongkey on August 20, 2021, 07:36:59 am
 :),

thanks prof JM, you are the best!

Actually i get more 1 solution for this:
for API > 18

Code: Java  [Select][+][-]
  1. public static boolean isMockLocationOn(Context context) {
  2.     if (Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ALLOW_MOCK_LOCATION).equals("0"))
  3.         return false;
  4.     else
  5.         return true;
  6. }
Title: Re: LAMW how to add function on jtelephony.java -> getAllCellInfo()?
Post by: Mongkey on August 20, 2021, 08:29:52 am
Working very well on android 10, just tested get cell location, is it compatible for dual sim android? I gonna test it soon!
Title: Re: LAMW (solved) how to prevent location mocking / fake gps on LAMW
Post by: Mongkey on August 21, 2021, 07:41:18 am
GetLocationAreaCode()
GetBaseStationId()
GetMobileNetworkCode()
GetMobileCountryCode()

After trying all, all retrieve same value :( (dual sim, sim1-> but with expiring telco subscription , no card on sim2), yesterday just tried GetLocationAreaCode(), not yet trying 3 others.

After inspecting -> working ok for dual sim -> detect on sim2 only, no card on sim1 -> WORK  :D

may be, retrieving same value if the card has expired -> useful for detecting no longer in service telco simcard  :)
Title: Re: LAMW (solved) how to prevent location mocking / fake gps on LAMW
Post by: engkin on August 22, 2021, 06:10:39 pm
This took me longer than I like. I kept having stange exception with an "invalid object". I tracked it down to a call in my code:
Code: Pascal  [Select][+][-]
  1.   javContext:=gApp.GetContext();//<---- fails

which is:
Code: Pascal  [Select][+][-]
  1. function jApp.GetContext(): jObject;
  2. begin
  3.   Result:= jApp_GetContext(Self.Jni.jEnv, Self.Jni.jThis);//<--- this fails!!
  4. end;

I assumed Self.Jni.jThis is not holding a valid value anymore, so I turned it into a Java global variable reference:
Code: Pascal  [Select][+][-]
  1. var
  2.   gThis:jobject;
  3.   gContext:jobject;
  4.  
  5. procedure Java_Event_pAppOnCreate(env: PJNIEnv; this: jobject; context:jobject; layout:jobject; intent: jobject);
  6. begin
  7.   gThis:=env^.NewGlobalRef(env,this);
  8.   gContext:=env^.NewGlobalRef(env,context);
  9.  
  10.   gApp.IsAppActivityRecreate := gApp.FInitialized;
  11.   gApp.FInitialized := False;
  12.   //gApp.Init(env,this,context,layout, intent);
  13.   gApp.Init(env,gThis,gContext,layout, intent);
  14. end;

Surprisingly that was not enough!!
then I skipped Self.Jni.jThis and used the global variable gThis directly:

Code: Pascal  [Select][+][-]
  1. function jApp.GetContext(): jObject;
  2. begin
  3.   Result:= jApp_GetContext(Self.Jni.jEnv, gThis);
  4. end;

Now it works:
Quote
<Init>
</Init>
<Context>
gApp.APILevel: 30
prob: 7
</Context>
<Activity>
</Activity>
pasContext.TELEPHONY_SERVICE:
phone
<TelephonyManager>
<getAllCellInfo>
<List>
pasList.size: 4
<Loop>
get(0)
CellInfo
CellInfoLte:{mRegistered=YES ....
get(1)
CellInfo
CellInfoLte:{mRegistered=NO ...
get(2)
CellInfo
CellInfoLte:{mRegistered=NO ...
get(3)
CellInfo
CellInfoLte:{mRegistered=NO ...
</Loop>
Title: Re: LAMW (solved) how to prevent location mocking / fake gps on LAMW
Post by: jmpessoa on August 22, 2021, 10:29:20 pm
Quote
function jApp.GetContext(): jObject;
begin
  Result:= jApp_GetContext(Self.Jni.jEnv, Self.Jni.jThis);//<--- this fails!!
end;


You can see in "Laz_And_Controls_Events.pas"  and "Laz_And_Controls.pas"

that all  "Java_Event_*"  call has some code like this:

Code: [Select]
Procedure Java_Event_pOnTimePicker(env: PJNIEnv; this: jobject; Obj: TObject; hourOfDay: integer; minute: integer);
begin

  gApp.Jni.jEnv := env;          // <----
  if this <> nil then gApp.Jni.jThis := this;      // <----

  ......
  .......
end; 

It keeps these global data always "up to date"!

the reference is here:

https://android-developers.googleblog.com/2011/11/jni-local-reference-changes-in-ics.html


Are you "by passing" LAMW code architecture?
Title: Re: LAMW (solved) how to prevent location mocking / fake gps on LAMW
Post by: engkin on August 22, 2021, 11:40:30 pm
No, I am not bypassing LAMW's architecture. I am trying to extend it by bringing Java/Android classes to Pascal.

As your reference link shows, Java_Event_pAppOnCreate is expected to use env->NewGlobalRef to store its parameters on the Pascal side, otherwise these values become invalid because of the Garbage Collector moving them around. How come you're not following that reference?  :-\

I made a simple app with a jButton and jEditText. The button calls javContext:=gApp.GetContext();

That call fails because gApp.Jni.jThis became invalid.
Then I used NewGlobalRef as soon as I received the parameters in Java_Event_pAppOnCreate
Passing the results to jApp.Init *seemed* not to work,
but NOW, thanks to your explanation, I think they got overwritten by LOCAL references again.

That explains why it worked when I used gThis directly,  because it holds the GLOBAL reference.

If my understanding is correct, there is a bug in LAMW, it should set the members of jApp.Jni once, AND it should use NewGlobalRef for that, AND it should not change them inside Java_Event_* in unit "Laz_And_Controls_Events.pas"  or any other place.

Of course, at the end of the app it should delete the global references.
Title: Re: LAMW (solved) how to prevent location mocking / fake gps on LAMW
Post by: jmpessoa on August 23, 2021, 12:29:13 am
So at the moment we are doing different readings of the document.....

this code:

Code: Pascal  [Select][+][-]
  1. Procedure Java_Event_pOnTimePicker(env: PJNIEnv; this: jobject; Obj: TObject; hourOfDay: integer; minute: integer);
  2. begin
  3.  
  4.   gApp.Jni.jEnv := env;          // <----
  5.   if this <> nil then gApp.Jni.jThis := this;      // <----
  6.  
  7.   ......
  8.   .......
  9. end;
  10.  

is vital for the entire LAMW code architecture ... and yes "gApp" is global, but  properties
gApp.Jni.jEnv and  gApp.Jni.jThis  need to be continually updated
otherwise we will get "staled"  object reference....
Title: Re: LAMW (solved) how to prevent location mocking / fake gps on LAMW
Post by: engkin on August 23, 2021, 01:44:47 am
When I said global, I was not talking about Pascal global variables.  I meant Jave global references. These references do not stall, the Garbage Collector doesn't touch them.

What you receive in Java_Event_* is Java local references, these local references will stall. If you intend to use them outside these procedures, as in LAMW, you're supposed to turn the Java local references to Java global references.

This is what the article you linked is saying, and it is what works on my side.

If you are not convinced, can you show me one simple example where my suggestion will not work?
Title: Re: LAMW (solved) how to prevent location mocking / fake gps on LAMW
Post by: jmpessoa on August 23, 2021, 04:16:09 am

Quote
can you show me one simple example where my suggestion .....

From reference:

Quote
Now there’s a per-thread local reference table, it’s vital that you only use a JNIEnv* on the right thread.

Quote
If you have a native peer (a long-lived native object corresponding to a Java object, usually created when the Java object is created and destroyed when the Java object’s finalizer runs), you must not stash a jobject in that native object, because it won’t be valid next time you try to use it. (Similar is true of JNIEnv*s. They might be valid if the next native call happens on the same thread, but they won’t be valid otherwise.)

and from here: https://developer.android.com/training/articles/perf-jni

Quote
The JNIEnv is used for thread-local storage. For this reason, you cannot share a JNIEnv between threads.


Remember that "LAMW Pascal" side/code  talk to "LAMW java" [multi-thread?] side/code..... 

So at some time if you comment out these two lines of code:

Quote
  gApp.Jni.jEnv := env;                             // <----
  if this <> nil then gApp.Jni.jThis := this;  // <--- 

you will get  a staled object reference .....

Title: Re: LAMW (solved) how to prevent location mocking / fake gps on LAMW
Post by: jmpessoa on August 23, 2021, 06:07:47 pm

Quote
I am trying to extend it by bringing Java/Android classes to Pascal.

There is a "conceptual" attempt here:
 
"Laz_And_jni_Controls.pas"  and demo "AppTest2"
Title: Re: LAMW (solved) how to prevent location mocking / fake gps on LAMW
Post by: engkin on August 23, 2021, 10:05:14 pm
Remember that "LAMW Pascal" side/code  talk to "LAMW java" [multi-thread?] side/code..... 

All I mentioned was for a single thread, and I am leaving JNIEnv out for now. Later both will be included. That's why I asked you for the simplest example. In the simplest case with a single thread and a single activity, any jobject we receive inside events is going to stale by the end of the event. If we need the object outside that event, then we need to turn it into a Java global reference.

For now, I can manage without any changes to LAMW. So let's keep LAMW as is.

There is a "conceptual" attempt here:
 
"Laz_And_jni_Controls.pas"  and demo "AppTest2"

Yes, this is what I want to do. Can you please correct me if I state something not accurate in any of the following:

I noticed IDs we get from calling Get_j*ID can be reused and we do not need to call Get_j*ID again for the same member.
For instance instead of:
Code: Pascal  [Select][+][-]
  1. procedure TAndroidListView.NotifyDataSetChanged(jAdapter: jObject);
  2. var
  3.   jClass_arrayAdapter: jClass;
  4.   jMethodId_notifyDataSetChanged:  jMethodID;
  5. begin
  6.   jClass_arrayAdapter:= Get_jClassLocalRef('android/widget/ArrayAdapter');
  7.   jMethodId_notifyDataSetChanged:= Get_jMethodID(jClass_arrayAdapter, 'notifyDataSetChanged','()V');
  8.   Call_jVoidMethod(jAdapter, jMethodId_notifyDataSetChanged);
  9. end;


we can write:
Code: Pascal  [Select][+][-]
  1. procedure TAndroidListView.NotifyDataSetChanged(jAdapter: jObject);
  2. begin
  3.   Call_jVoidMethod(jAdapter, jMethodId_notifyDataSetChanged);
  4. end;

Assuming jMethodId_notifyDataSetChanged declared as a "static" member of the TAndroidListView and has the correct value.
Title: Re: LAMW (solved) how to prevent location mocking / fake gps on LAMW
Post by: engkin on August 23, 2021, 10:25:07 pm

Quote
I am trying to extend it by bringing Java/Android classes to Pascal.

There is a "conceptual" attempt here:
 
"Laz_And_jni_Controls.pas"  and demo "AppTest2"

I just installed this example on my phone, and now I want to know what problems did you face to prevent you from moving in this direction?
Asked in a different way, why do you keep adding to the Java part?
Title: Re: LAMW (solved) how to prevent location mocking / fake gps on LAMW
Post by: jmpessoa on August 23, 2021, 11:38:04 pm
Quote
I want to know what problems did you face to prevent you from moving in this direction?

just absolute lack of time.....

Quote
Asked in a different way, why do you keep adding to the Java part?

0) LAMW "GUI" was the way found after experiences/trials [and frustrations] for me and for many others (felipemdc, simonsayz, .... )

1) Code reuse: thousands of java/android tutorials deliver ready-to-use solutions....

2) we can embed all the logic (including asynchronous routines, exception handle, ....) in java side and leaving to pascal only the work of making the methods calls and responding to the events ..... making code generation [and use] on the pascal side "clear" and easier.

side note 1: yes, it is still possible other approaches in LAMW "GUI" and "fixes" including your suggestion about a global "gThis"
but we need a lot of [time and] code refactoring, testing/maturation  otherwise we run the risk of break/stop  everything [legacy] that is working ....

side note 2: @loaded is working in another direction:  LAMW "NoGUI"
Title: Re: LAMW (solved) how to prevent location mocking / fake gps on LAMW
Post by: loaded on August 25, 2021, 02:30:19 pm
side note 2: @loaded is working in another direction:  LAMW "NoGUI"

LAMW, The Platform that pushes the limits of the possible.
We can't thank enough the legendary developers of LAMW for bringing this masterpiece to us.

It's up to your imagination and skills to do what you want with NoGUI...

https://youtu.be/SCAOeAN3eU4 (https://youtu.be/SCAOeAN3eU4) In this study, I wanted to show how .so files created with LAMW module can be used in Android Studio.

https://youtu.be/gBS0AMrJ50s (https://youtu.be/gBS0AMrJ50s) Also, the CAD application named Polygon, which I wrote with this method; He started running, he will be in the 1st league soon :)
Title: Re: LAMW (solved) how to prevent location mocking / fake gps on LAMW
Post by: Mongkey on August 27, 2021, 10:02:00 am
Amazing !  :o
TinyPortal © 2005-2018