[关闭]
@mSolo 2015-04-10T15:17:08.000000Z 字数 6532 阅读 2469

Android IPC/Binder Framework 实战(下)

Android IPC 框架 实战


笔记
https://thenewcircle.com/s/post/1340/Deep_Dive_Into_Binder_Presentation.htm

Async Binder IPC 实战

https://github.com/mSoloYu/AsyncStockQuoteDemo.git

AsyncStockQuoteAidl

  1. import com.stockquote.aidl.StockQuoteRequest;
  2. import com.stockquote.aidl.IStockQuoteServiceResponseListener;
  3. oneway interface IStockQuoteService {
  4. void retrieveStockQuote(in StockQuoteRequest request, in IStockQuoteServiceResponseListener listener);
  5. }
  6. import com.stockquote.aidl.StockQuoteResponse;
  7. oneway interface IStockQuoteServiceResponseListener {
  8. void onResponse(in StockQuoteResponse response);
  9. }

AsyncStockQuoteServer

  1. public class StockQuoteServiceImpl extends IStockQuoteService.Stub {
  2. @Override
  3. public void retrieveStockQuote(StockQuoteRequest request, IStockQuoteServiceResponseListener listener) throws RemoteException {
  4. String[] stockIdArray = null;
  5. if (request.getType() == StockQuoteRequest.Type.STOCKQUOTE_MULTIPLE) {
  6. stockIdArray = request.getStockIdArray();
  7. } else {
  8. return ;
  9. }
  10. StockQuote stockQuote = StockNetResourceManager.getInstance()
  11. .setUpStockQuotes(stockIdArray);
  12. listener.onResponse(new StockQuoteResponse(stockQuote));
  13. }
  14. }

AsyncStockQuoteClient

  1. public class MainActivity extends Activity
  2. implements ServiceConnection {
  3. private static final String TAG = "MainActivity";
  4. private static final int RESPONSE_MESSAGE_ID = 1;
  5. private ProgressDialog mDialog;
  6. private TextView mNameTv;
  7. private TextView mQuoteTv;
  8. private IStockQuoteService mService;
  9. private final Handler responseHandler = new Handler() {
  10. @Override
  11. public void handleMessage(Message message) {
  12. switch (message.what) {
  13. case RESPONSE_MESSAGE_ID:
  14. mNameTv.setText(((StockQuote) message.obj).getStockName());
  15. mQuoteTv.setText( ((StockQuote)message.obj).getStockPrice() );
  16. mDialog.dismiss();
  17. break;
  18. }
  19. }
  20. };
  21. private final IStockQuoteServiceResponseListener responseListener
  22. = new IStockQuoteServiceResponseListener.Stub() {
  23. // this method is executed on one of the pooled binder threads
  24. @Override
  25. public void onResponse(StockQuoteResponse response)
  26. throws RemoteException {
  27. Message message = responseHandler
  28. .obtainMessage(RESPONSE_MESSAGE_ID, response.getResult());
  29. responseHandler.sendMessage(message);
  30. }
  31. };
  32. @Override
  33. protected void onCreate(Bundle savedBundle) {
  34. super.onCreate(savedBundle);
  35. setContentView(R.layout.main);
  36. mNameTv = (TextView) findViewById(R.id.name);
  37. mQuoteTv = (TextView) findViewById(R.id.quote);
  38. }
  39. @Override
  40. protected void onResume() {
  41. super.onResume();
  42. if (!super.bindService(new Intent(IStockQuoteService.class.getName()),
  43. this, BIND_AUTO_CREATE)) {
  44. }
  45. }
  46. @Override
  47. protected void onPause() {
  48. super.onPause();
  49. super.unbindService(this);
  50. }
  51. public void onServiceConnected(ComponentName name, IBinder service) {
  52. mService = IStockQuoteService.Stub.asInterface(service);
  53. setText();
  54. }
  55. public void onServiceDisconnected(ComponentName name) {
  56. mService = null;
  57. }
  58. private void setText() {
  59. final StockQuoteRequest request = new StockQuoteRequest(null,
  60. new String[]{"002024"}, StockQuoteRequest.Type.STOCKQUOTE_MULTIPLE);
  61. mDialog = ProgressDialog.show(this, "",
  62. "正在获取...", true);
  63. try {
  64. mService.retrieveStockQuote(request, responseListener);
  65. } catch (RemoteException e) {
  66. mDialog.dismiss();
  67. return ;
  68. }
  69. }
  70. }

Binder Security

  1. static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
  2. {
  3. switch (cmd) {
  4. case BINDER_SET_CONTEXT_MGR:
  5. if (binder_context_mgr_node != NULL) {
  6. printk(KERN_ERR "binder: BINDER_SET_CONTEXT_MGR already set\n");
  7. ret = -EBUSY;
  8. goto err;
  9. }
  10. binder_context_mgr_node = binder_new_node(proc, NULL, NULL);
  11. }

一旦我们知道了对方的 UID,我们就能得到对方的 app 信息:PackageManager.getPackagesForUid(int uid)
一旦我们知道了对方的app,我们就能得到对方的权限信息:PackageManager.getPackageInfo(String packageName, int flags) (with the PackageManager.GET_PERMISSIONS flag)

实战

SecurityStockQuoteService

  1. <!-- res/values/strings.xml -->
  2. <resources>
  3. <string name="stockquote_permissions_group_label">StockQuote Permissions
  4. </string>
  5. </resources>
  6. <!-- AndroidManifest.xml ,permission-group 为可选配置-->
  7. <permission-group
  8. android:name="com.stockquote.service.STOCKQUOTE_PERMISSIONS"
  9. android:label="@string/stockquote_permissions_group_label" />
  1. <resources>
  2. <string name="use_stockquote_service_permission_label">use stockquote service</string>
  3. <string name="use_stockquote_service_permission_description">
  4. applications with this permissions get stockquote results for free
  5. </string>
  6. </resources>
  7. <manifest>
  8. <permission-group/>
  9. <permission
  10. android:name="com.stockquote.service.USE_STOCKQUOTSE_SERVICE"
  11. android:description="@string/use_stockquote_service_permission_description"
  12. android:label="@string/use_stockquote_service_permission_label"
  13. android:permissionGroup="com.stockquote.service.STOCKQUOTPE_PERMISSIONS"
  14. android:protectionLevel="dangerous" />
  15. <application>
  16. <service
  17. android:name=".StockQuoteService"
  18. android:permission="com.stockquote.service.USE_STOCKQUOTSE_SERVICE" >
  19. </service>
  20. </application>
  21. </manifest>

SecurityStockQuoteClient

  1. <manifest>
  2. <uses-permission android:name="com.stockquote.service.USE_STOCKQUOTE_SERVICE"/>
  3. </manifest>
  1. public class StockQuoteServiceImpl extends IStockQuoteService.Stub {
  2. private final Context context;
  3. public StockQuoteServiceImpl(Context context) {
  4. this.context = context;
  5. }
  6. private long checkN(long n) {
  7. if (n > 10) {
  8. this.context.enforceCallingOrSelfPermission(
  9. Manifest.permission.USE_SLOW_STOCKQUOTSE_SERVICE, "Go away!");
  10. }
  11. return n;
  12. }
  13. }

其他 Binder 特性

  1. public class LocationManagerService extends ILocationManager.Stub implements Runnable {
  2. private Receiver getReceiver(ILocationListener listener) {
  3. IBinder binder = listener.asBinder();
  4. Receiver receiver = mReceivers.get(binder);
  5. if (receiver == null) {
  6. receiver = new Receiver(listener);
  7. receiver.getListener().asBinder().linkToDeath(receiver, 0);
  8. }
  9. return receiver;
  10. }
  11. private final class Receiver implements IBinder.DeathRecipient, PendingIntent.OnFinished {
  12. final ILocationListener mListener;
  13. Receiver(ILocationListener listener) {
  14. mListener = listener;
  15. }
  16. public void binderDied() {
  17. removeUpdatesLocked(this);
  18. }
  19. }
  20. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注