The documentation states that
all non-primitive parameters require a directional tag indicating which way the data goes; and
primitives are in by default, and cannot be otherwise.
Then they proceed with giving an example where a String is missing the directional tag. Can a String be out or inout in Android AIDL?
Since strings are immutable I'd have to do an assignment on the method handling the call in order to change the string, something like myString = "hello to you too";. I know that in a regular method this argument myString would remain unchanged at the caller side. Is that behavior applied here?
Related
This might be a very silly question, but I am logging the methods that are triggered in my app as strings. When an issue is submitted, I would like to automatically input the text of the strings as parameters for methods. E.g:
For method:
fun assignPot(potType: PotType, ball: DomainBall, action: PotAction) {...}
I'd like to somehow call method:
assignPot(FOUL(2, BLUE(5), SWITCH))
From String:
"FOUL(2, BLUE(5), SWITCH)"
The only workaround I can think of is to split the string and create a when -> then function to get actual classes from strings, but I wondered if there's a more concise way for this.
This is not what you want to do. You should design your app in a way that prevents users from providing input similar to actual code.
However, you can achieve this. Complex parsings like this oftenly use regex-based approaches.
As you said, you should map your string part to class. If your PotType is enum, you can do something like
val re = Regex("[^A-Za-z\s]")
val reNumbers = Regex("[^0-9\s]")
// get classes
val classNames = originalString.replace(re, "").split(" ")
// get their constructor numerical arguments
val classArgs = originalString.replace(reNumbers, "").split(" ")
After that you can implement mapping with when expression. You probably will use some collection of Any type.
As you see, this sadly leads you to parsing code by code. Concise way to solve is to implement your own script compiler/interpreter and use it in your application :) That will later lead you to dealing with security breaches and so on.
If you are logging problematic method calls and want to repeat them immediately after issue is submitted, you probably want to programatically save the calls to lambdas and call them when you receive an issue log.
I have a class, say A, in Java with few methods and some static variables.
I am building a WebView based application in Android. I have injected an instance of class A using addJavascriptInterface method. (The application is actually using Phonegap)
I have a Javascript function which performs RSA Encryption using public key K(n, e) passed to it.
encryptString(n, e);
The 'n' is returned by a method from class A, called like:
var keyn = window.A.load("publicKey");
This is where I have a problem. When I pass 'n' as string, and 'e' = "10001" as string too, the encryption works well. But, when I pass keyn recived from the method, it doesnt work.
encryptString("42342abcdefg2232", "10001"); // Works
encryptString(keyn, "10001"); // Doesn't work :(
I have logged keyn in logcat and it shows that value is recived correctly in the variable keyn.
What is the problem then?
PS: I have tried two different RSA encryption libraries and same problem with both. So, most probably it is not a problem in the encryption code I am using.
The solution I found was that I passed keyn as new String(keyn) and it worked. In the journey I found the differences between string literal and string object in Javascript. I suppose WebView basically returns an Object and we need to convert it to string object before passing it to the function.
Anyone who could elaborate it more is welcome.
I wanted to know what is the inout param in the AIDL is for?
I know what is in for and what out is for. (out does not marshal the object passing).
But I don't understand what is the inout for.
I have looked in the:
"In/out/inout" in a AIDL interface parameter value?
question but still did not understand.
From my testings the param is passed much like specifying it as in.
So if any1 can shed some light on what is inout It would be helpful.
Thanks
An in parameter is only transported from the caller to the callee. An out parameter is transported from the callee to the caller. And an inout parameter is transported both ways.
You would use an inout paramter when you pass an object to the callee and the callee changes it.
Here it my version of explaining the directional tags in AIDL,
Its only a directional tag indicating which way the data goes.
in - object is transferred from client to service only used for
inputs
out - object is transferred from client to service only used
for outputs.
inout - object is transferred from client to service
used for both inputs and outputs.
All non-primitive parameters require a directional tag indicating which way the data goes. Either in, out, or inout.
Primitives are in by default, and cannot be otherwise
Please note, RPC calls from clients are synchronous.
You should limit the direction to what is truly needed, because marshaling parameters is expensive.
Example:
Please check the below AIDL interface to understand it in a better way.
package com.hardian.sample.aidl;
import com.hardian.sample.aidl.TeamMember;
interface ITeamManageService {
void getTeamCaptian(out TeamMember member);
void updateTeamMember(inout TeamMember member, in boolean isLeader);
oneway void removeTeamMember(in TeamMember member);
}
Here we have used out, in, inout directional tags to indicate which way the data goes.
getTeamCaptian(out TeamMember member) :
Get the captain of the team.
Here the "out" directional tag means, when the client calls this method, the "member" object has no relevant data,
but the server shall make changes to the "member" object, so the client shall get the updated "member" object.
In fact, the method call is synchronous.
updateTeamMember(inout TeamMember member, in boolean isLeader) :
Update the captian of the team.
Here the "inout" directional tag means, when the client calls this method,the "member" object has relevant data in it.
And the server shall use the input data and process it. Once the process completed, the client shall get the relevant data back.
In fact, the method call is synchronous.
removeTeamMember(in TeamMember member)
Remove a member from the team.
Here the "in" directional tag means, the "member" object is transferred from client to service only used for inputs.
If any changes are made to the "member" object in the service then it won’t reflect in the client.
The method call is asynchronous, we can put the "oneway" keyword to the method signature.
Asynchronous methods must not have "out" and "inout" arguments, they must also return void.
sometimes printf("%p", this) helps to see different instances.
What's the equivalent of that in android?
(to print out address of this variable or something unique(it may not be address) to the instance)
It seems I can new interface like OnTouchListener then, how do I print something to differentiate the different instances of them?
Something like this should do it:
android.util.Log.i("Instance", "This is: " + this);
By default, the toString implementation of Object will print the class type plus a hash code which can be considered somewhat equivalent to the this pointer in C++.
The toString method for class Object returns a string consisting of the name of the class of which the object is an instance, the at-sign character '#', and the unsigned hexadecimal representation of the hash code of the object. In other words, this method returns a string equal to the value of:
getClass().getName() + '#' + Integer.toHexString(hashCode())
If an object provides a different implementation of toString(), like for instance String does, then you can use the above canonical implementation of the base toString() method to get the same results.
To get something distinct to the instance, you should use System.identityHashCode(this). It returns what the default implementation of .hashCode() in Object returns (which may have been overridden in subclasses, so that's why you shouldn't use .hashCode() directly), which, according to the documentation, is "As much as is reasonably practical" distinct for distinct objects.
I'm programming a radio streaming app. I run the "radio playing" as a remote Service by using AIDL interface technique to communicate with the Service. But I don't really understand one thing.
What is the "out" in a AIDL interface parameter value?
Like this:
String doSomething(in String a, out String[] b);
I understand "in", that is sending data to the remote when the method is called from activity.
What is the "out", and why we need "in" and "out" in same method? In which case are they("out/inout") used? Why is the String[] "out"?
Please help..
In AIDL, the out tag specifies an output-only parameter. In other words, it's a parameter that contains no interesting data on input, but will be filled with data during the method.
For example, a method that copies an array of bytes might be specified like this:
void copyArray(in byte[] source, out byte[] dest);
The inout tag indicates that the parameter has meaning on both input and output. For example:
void charsToUpper(inout char[] chars);
This is important because the contents of every parameter must be marshalled (serialized, transmitted, received, and deserialized). The in/out tags allow the Binder to skip the marshalling step for better performance.
Here it goes,
Its only a directional tag indicating which way the data goes.
in - object is transferred from client to service only used for
inputs
out - object is transferred from client to service only used
for outputs.
inout - object is transferred from client to service
used for both inputs and outputs.
All non-primitive parameters require a directional tag indicating which way the data goes. Either in, out, or inout.
Primitives are in by default, and cannot be otherwise
Please note, RPC calls from clients are synchronous.
You should limit the direction to what is truly needed, because marshaling parameters is expensive.
Example:
Please check the below AIDL interface to understand it in a better way.
package com.hardian.sample.aidl;
import com.hardian.sample.aidl.TeamMember;
interface ITeamManageService {
void getTeamCaptian(out TeamMember member);
void updateTeamMember(inout TeamMember member, in boolean isLeader);
oneway void removeTeamMember(in TeamMember member);
}
Here we have used out, in, inout directional tags to indicate which way the data goes.
getTeamCaptian(out TeamMember member) :
Get the captain of the team.
Here the "out" directional tag means, when the client calls this method, the "member" object has no relevant data,
but the server shall make changes to the "member" object, so the client shall get the updated "member" object.
In fact, the method call is synchronous.
updateTeamMember(inout TeamMember member, in boolean isLeader) :
Update the captian of the team.
Here the "inout" directional tag means, when the client calls this method,the "member" object has relevant data in it.
And the server shall use the input data and process it. Once the process completed, the client shall get the relevant data back.
In fact, the method call is synchronous.
removeTeamMember(in TeamMember member)
Remove a member from the team.
Here the "in" directional tag means, the "member" object is transferred from client to service only used for inputs.
If any changes are made to the "member" object in the service then it won’t reflect in the client.
The method call is asynchronous, we can put the "oneway" keyword to the method signature.
Asynchronous methods must not have "out" and "inout" arguments, they must also return void.