@mSolo
2015-04-10T15:17:08.000000Z
字数 6532
阅读 2469
Android
IPC
框架
实战
笔记
https://thenewcircle.com/s/post/1340/Deep_Dive_Into_Binder_Presentation.htm
import com.stockquote.aidl.StockQuoteRequest;
import com.stockquote.aidl.IStockQuoteServiceResponseListener;
oneway interface IStockQuoteService {
void retrieveStockQuote(in StockQuoteRequest request, in IStockQuoteServiceResponseListener listener);
}
import com.stockquote.aidl.StockQuoteResponse;
oneway interface IStockQuoteServiceResponseListener {
void onResponse(in StockQuoteResponse response);
}
public class StockQuoteServiceImpl extends IStockQuoteService.Stub {
@Override
public void retrieveStockQuote(StockQuoteRequest request, IStockQuoteServiceResponseListener listener) throws RemoteException {
String[] stockIdArray = null;
if (request.getType() == StockQuoteRequest.Type.STOCKQUOTE_MULTIPLE) {
stockIdArray = request.getStockIdArray();
} else {
return ;
}
StockQuote stockQuote = StockNetResourceManager.getInstance()
.setUpStockQuotes(stockIdArray);
listener.onResponse(new StockQuoteResponse(stockQuote));
}
}
public class MainActivity extends Activity
implements ServiceConnection {
private static final String TAG = "MainActivity";
private static final int RESPONSE_MESSAGE_ID = 1;
private ProgressDialog mDialog;
private TextView mNameTv;
private TextView mQuoteTv;
private IStockQuoteService mService;
private final Handler responseHandler = new Handler() {
@Override
public void handleMessage(Message message) {
switch (message.what) {
case RESPONSE_MESSAGE_ID:
mNameTv.setText(((StockQuote) message.obj).getStockName());
mQuoteTv.setText( ((StockQuote)message.obj).getStockPrice() );
mDialog.dismiss();
break;
}
}
};
private final IStockQuoteServiceResponseListener responseListener
= new IStockQuoteServiceResponseListener.Stub() {
// this method is executed on one of the pooled binder threads
@Override
public void onResponse(StockQuoteResponse response)
throws RemoteException {
Message message = responseHandler
.obtainMessage(RESPONSE_MESSAGE_ID, response.getResult());
responseHandler.sendMessage(message);
}
};
@Override
protected void onCreate(Bundle savedBundle) {
super.onCreate(savedBundle);
setContentView(R.layout.main);
mNameTv = (TextView) findViewById(R.id.name);
mQuoteTv = (TextView) findViewById(R.id.quote);
}
@Override
protected void onResume() {
super.onResume();
if (!super.bindService(new Intent(IStockQuoteService.class.getName()),
this, BIND_AUTO_CREATE)) {
}
}
@Override
protected void onPause() {
super.onPause();
super.unbindService(this);
}
public void onServiceConnected(ComponentName name, IBinder service) {
mService = IStockQuoteService.Stub.asInterface(service);
setText();
}
public void onServiceDisconnected(ComponentName name) {
mService = null;
}
private void setText() {
final StockQuoteRequest request = new StockQuoteRequest(null,
new String[]{"002024"}, StockQuoteRequest.Type.STOCKQUOTE_MULTIPLE);
mDialog = ProgressDialog.show(this, "",
"正在获取...", true);
try {
mService.retrieveStockQuote(request, responseListener);
} catch (RemoteException e) {
mDialog.dismiss();
return ;
}
}
}
…
static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
…
switch (cmd) {
…
case BINDER_SET_CONTEXT_MGR:
if (binder_context_mgr_node != NULL) {
printk(KERN_ERR "binder: BINDER_SET_CONTEXT_MGR already set\n");
ret = -EBUSY;
goto err;
}
…
binder_context_mgr_node = binder_new_node(proc, NULL, NULL);
…
}
…
…
一旦我们知道了对方的 UID,我们就能得到对方的 app 信息:PackageManager.getPackagesForUid(int uid)
一旦我们知道了对方的app,我们就能得到对方的权限信息:PackageManager.getPackageInfo(String packageName, int flags) (with the PackageManager.GET_PERMISSIONS flag)
<!-- res/values/strings.xml -->
<resources>
<string name="stockquote_permissions_group_label">StockQuote Permissions
</string>
</resources>
<!-- AndroidManifest.xml ,permission-group 为可选配置-->
<permission-group
android:name="com.stockquote.service.STOCKQUOTE_PERMISSIONS"
android:label="@string/stockquote_permissions_group_label" />
<resources>
…
<string name="use_stockquote_service_permission_label">use stockquote service</string>
<string name="use_stockquote_service_permission_description">
applications with this permissions get stockquote results for free
</string>
…
</resources>
<manifest …>
…
<permission-group …/>
<permission
android:name="com.stockquote.service.USE_STOCKQUOTSE_SERVICE"
android:description="@string/use_stockquote_service_permission_description"
android:label="@string/use_stockquote_service_permission_label"
android:permissionGroup="com.stockquote.service.STOCKQUOTPE_PERMISSIONS"
android:protectionLevel="dangerous" />
…
<application …>
<service
android:name=".StockQuoteService"
android:permission="com.stockquote.service.USE_STOCKQUOTSE_SERVICE" >
…
</service>
</application>
</manifest>
<manifest …>
…
<uses-permission android:name="com.stockquote.service.USE_STOCKQUOTE_SERVICE"/>
…
</manifest>
public class StockQuoteServiceImpl extends IStockQuoteService.Stub {
…
private final Context context;
public StockQuoteServiceImpl(Context context) {
this.context = context;
}
private long checkN(long n) {
if (n > 10) {
this.context.enforceCallingOrSelfPermission(
Manifest.permission.USE_SLOW_STOCKQUOTSE_SERVICE, "Go away!");
}
return n;
}
…
}
public class LocationManagerService extends ILocationManager.Stub implements Runnable {
…
private Receiver getReceiver(ILocationListener listener) {
IBinder binder = listener.asBinder();
Receiver receiver = mReceivers.get(binder);
if (receiver == null) {
receiver = new Receiver(listener);
…
receiver.getListener().asBinder().linkToDeath(receiver, 0);
…
}
return receiver;
}
private final class Receiver implements IBinder.DeathRecipient, PendingIntent.OnFinished {
final ILocationListener mListener;
…
Receiver(ILocationListener listener) {
mListener = listener;
…
}
…
public void binderDied() {
…
removeUpdatesLocked(this);
}
…
}
…
}