Presentation is loading. Please wait.

Presentation is loading. Please wait.

1 Mobile Software Development Framework: Android IPC; Mobile Push Notification 10/16/2012 Y. Richard Yang.

Similar presentations


Presentation on theme: "1 Mobile Software Development Framework: Android IPC; Mobile Push Notification 10/16/2012 Y. Richard Yang."— Presentation transcript:

1 1 Mobile Software Development Framework: Android IPC; Mobile Push Notification 10/16/2012 Y. Richard Yang

2 2 Outline r Admin r Android Inter-process communications r Mobile push notification

3 3 Admin. r Schedule for the rest of semester

4 Recap: Event Handler Execution 4 r Event handler (EH) executed by the main/UI thread’s Looper r Slow EH blocks event processing r Guidelines m Notify user m Incremental update m Short/non- blocking handler, real processing offloaded to other thread UI events system events message Looper UI (main) thread

5 Recap: Background/UI Contention 5 public class LoadingScreen extends Activity implements Runnable { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.loading); // start a new thread to load Thread thread = new Thread(this); thread.start(); } public void run(){ longRunningTask(); setContentView(R.layout.main); } … } Conflict with UI thread

6 Recap: Android Handler 6 Background thread sends msg through handler to UI thread, who processes the msg

7 Recap: Fixing LoadingScreen 7 public class LoadingScreen extends Activity implements Runnable { private Handler mHandler = new Handler(); // UI handler @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.loading); // start a new thread to load Thread thread = new Thread(this); thread.start(); } public void run(){ longTask(); mHandler.post(mSetFinalViewTask); } private Runnable mSetFinalViewTask = new Runnable() { public void run() { setContentView(R.layout.main); } }; } Conflict with UI thread

8 8 Recap: Inter-Process Communications (IPC) r Objective: reuse existing data and services among Android components

9 9 Recap: Inter-Process Communications (IPC) Component Activity Component Service Component Broadcast Receiver startActivity() startActivityForResult() startService() bindService() broadcastIntent()

10 Recap: Intent Data Structure r Primary pieces of info in an Intent m Action: The general action to be performed ACTION_VIEW, ACTION_DIAL, ACTION_EDIT, … Your own definition of strings m Data: a URI tel:123 content://contacts/people/1 http://zoo.cs.yale.edu/classes/cs434 hotel://name/Omni_New_Haven r Other attributes m Category m Type (MIME type) m Component (class name) m Extras (key-value store) 10 scheme host path

11 Explicit Intent 11 Yelp Map App class: MapActivity To: MapActivity.class Only the specified activity receives this message http://developer.android.com/training/basics/firstapp/starting-activity.html

12 Declare Activity in Manifest 12 r Make sure AndroidManifest.xml announces activities that can be started <application android:icon="@drawable/icon” android:label="@string/app_name" > <activity android:name=".IntentController” android:label="IntentController" > <activity android:name=".TipCal" android:label="TipCal" > Shown in Launcher Announce class See IntentController

13 Intent Resolution: Explicit Intent 13 public class IntentController extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.intentcontroller); // launch tip cal button Button tipBtn = (Button) findViewById(R.id.tipButton); tipBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent tipIntent = new Intent(IntentController.this, TipCal.class); startActivity(tipIntent); } }); class name Context start activity

14 StartActivity for Result: Caller 14 private void startGame() { Intent launchGame = new Intent(this, CoolGameA.class); // passing information to launched activity launchGame.putExtra("userName", userName); launchGame.putExtra("userScore", userScore); startActivityForResult(launchGame, PLAY_GAME); }

15 StartActivity for Result: Called 15 public class CoolGameA extends Activity { private TextView tv2; int previousScore, score; String user; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.game); tv2 = (TextView) findViewById(R.id.game_text); //Get the intent that started this activity to fetch passed info Intent i = getIntent(); //returns [] if not initialized by calling activity user = i.getStringExtra("userName"); //returns -1 if not initialized by calling activity previousScore = i.getIntExtra("userScore", -1); tv2.setText(user + ":" + previousScore); doSessionWithInput(user, previousScore);

16 StartActivity for Result: Callee 16 //change values for an example of return score = previousScore - 41; //setup button listener Button startButton = (Button) findViewById(R.id.end_game); startButton.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { //return information to calling activity Intent i = getIntent(); i.putExtra("returnScore", score); i.putExtra("returnName", user); setResult(RESULT_OK, i); finish(); } }); }

17 StartActivity for Result: Caller 17 private void startGame() { Intent launchGame = new Intent(this, CoolGameA.class); // passing information to launched activity launchGame.putExtra("userName", userName); launchGame.putExtra("userScore", userScore); startActivityForResult(launchGame, PLAY_GAME); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == PLAY_GAME && resultCode == RESULT_OK) { userName = data.getExtras().getString(”returnName"); userScore = data.getExtras().getInt(“returnScore"); // show it has changed tv.setText(userName + ":" + userScore); } super.onActivityResult(requestCode, resultCode, data); }

18 Explicit Intent: Start Service 18 public class PlayMusicService extends Service { public void onCreate() { super.onCreate(); } public int onStartCommand(Intent intent, int flags, int startId) { play_music(); return 1; } private void play_music() { while (true) { play_music_note(currentIndex); currentIndex++; } } // end of play_music http://developer.android.com/guide/components/services.html

19 Discussion r Problem of explicit intent 19

20 20 Outline r Admin r Android Inter-process communications m Intent data structure m Explicit intent m Implicit intent

21 Intent Resolution: Implicit Intent r Intent does not specify exact class to run m Info in the Intent used by the system to determine the best component, at run time, to handle the intent 21

22 Implicit Intents 22 Yelp Browser A Handles Action: VIEW Implicit Intent Action: VIEW

23 Implicit Intents 23 Yelp Browser B Browser A Handles Action: VIEW Implicit Intent Action: VIEW

24 Intent Filter r Problem: how to know what an Activity/Service can handle? r Solution: Activities/Services/Receivers declare what they can/want to receive in Intent filter 24 action category data http://developer.android.com/guide/topics/intents/intents-filters.html

25 Intent Filter: Example r AndroidManifest.xml file for com.android.browser 25 String action = "android.intent.action.VIEW"; Uri data = Uri.parse("http://www.google.com"); Intent myIntent = new Intent(action, data); startActivity(myIntent);

26 Implicit Start Activity 26 public class IntentController extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.intentcontroller); // launch dial button Button dialBtn = (Button) findViewById(R.id.dialButton); dialBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String action = "android.intent.action.DIAL"; String phno = "tel:4326400"; Uri data = Uri.parse(phno); Intent dialIntent = new Intent(action, data); startActivity(tipIntent); } }); data action See IntentController

27 A Design Template: Provider 27

28 A Design Template: Provider 28 @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Intent intent = getIntent(); // why am I called String action = intent.getAction(); Uri data = intent.getdata(); String hotelName = data.getPath(); // do the booking setResult(RESULT_OK); finish(); }

29 A Design Template: Invoker 29 String action = “com.hotelapp.ACTION_BOOK"; String hotel = “hotel://name/“ + selectedHotel; Uri data = Uri.parse(hotel); Intent bookingIntent = new Intent(action, data); startActivityForResults(bookingIntent, requestCode);

30 30 Outline r Admin r Android Inter-process communications m Intent data structure m Explicit intent m Implicit intent m Content provider as target of intent

31 Content Provider r Enable uniformed API for sharing data across applications m E.g., Address book, photo gallery r Each provider can expose its data as a simple table on a database model m Query, delete, update, and insert rows 31

32 Content Provider and Intent r Each content provider exposes a public URI that uniquely identifies its data set: m android.provider.Contacts.Phones.CONTENT_URI android.provider.Contacts.Photos.CONTENT_URI android.provider.CallLog.Calls.CONTENT_URI android.provider.Calendar.CONTENT_URI r A content consumer declares access requirement m 32

33 Content Consumer private void pickContact() { // Create an intent to "pick" a contact, as defined by the content provider URI Intent intent = new Intent(Intent.ACTION_PICK, Contacts.CONTENT_URI); startActivityForResult(intent, PICK_CONTACT_REQUEST); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { // If the request went well (OK) and the request was PICK_CONTACT_REQUEST if (resultCode == Activity.RESULT_OK && requestCode == PICK_CONTACT_REQUEST) { // Perform a query to the contact's content provider for the contact's name Cursor cursor = getContentResolver().query(data.getData(), new String[] {Contacts.DISPLAY_NAME}, null, null, null); if (cursor.moveToFirst()) { // True if the cursor is not empty int columnIndex = cursor.getColumnIndex(Contacts.DISPLAY_NAME); String name = cursor.getString(columnIndex); // Do something with the selected contact's name... } } } 33

34 34 Outline r Admin r Android Inter-process communications m Intent data structure m Explicit intent m Implicit intent m Content provider as target of intent m Broadcast intent

35 Broadcast Intents r Multiple components may be interested in an event/update m e.g., system event such as an incoming phone call, battery level low, network cell changes m receives notification by declaring a broadcast receiver 35

36 Intent and Broadcast: Sender String action = "edu.yale.cs434.RUN"; Intent cs434BroadcastIntent = new Intent(action); cs434BroadcastIntent.putExtra("message", "Wake up."); sendBroadcast(cs434BroadcastIntent); 36 Example: IntentController

37 Intent and Broadcast: Receiver 37

38 Intent, Broadcast, Receiver, Notification public class CS434BroadcastReceiver extends BroadcastReceiver { public static final String CUSTOM_INTENT = "edu.yale.cs434.RUN"; // Display an alert that we've received a message. @Override public void onReceive(Context context, Intent intent) { if (intent.getAction().equals(CUSTOM_INTENT)) { String message = (String)intent.getExtras().get("message"); CharSequence text = "Got intent " + CUSTOM_INTENT + " with " + message; int duration = Toast.LENGTH_SHORT; Toast mToast = Toast.makeText(context, text, duration); mToast.show(); } // end of if } // end of onReceive } 38

39 Intent, Broadcast, Receiver, Notification public class MyPhoneReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Bundle extras = intent.getExtras(); if (extras != null) { String state = extras.getString(TelephonyManager.EXTRA_STATE); if (state.equals(TelephonyManager.EXTRA_STATE_RINGING)) { String phoneNumber = extras.getString(TelephonyManager.EXTRA_INCOMING_NUMBER); Toast.makeText(context, "Incoming number: "+phoneNumber, Toast.LENGTH_LONG).show(); } // end of if } // end of onReceive } 39

40 Discussion: Downside of Implicit Intent 40

41 Real Example App: iMDb 41

42 Example App 42 Showtime Search Results UI IMDb App Handles Actions: willUpdateShowtimes, showtimesNoLocationError Implicit Intent Action: willUpdateShowtimes

43 43 Vulnerability: Eavedropping Showtime Search Malicious Receiver IMDb App Handles Action: willUpdateShowtimes, showtimesNoLocationError Implicit Intent Action: willUpdateShowtimes Eavesdropping App Sending Implicit Intents makes communication public

44 44 Vulnerability: Spoofing Malicious Component Results UI IMDb App Handles Action: willUpdateShowtimes, showtimesNoLocationError Action: showtimesNoLocationError Malicious Injection App Receiving Implicit Intents makes the component public

45 45 Vulnerability: Man-in-the-Middle Showtime Search Results UI IMDb App Handles Action: willUpdateShowtimes, showtimesNoLocation Error Malicious Receiver Handles Action: willUpdateShowtimes, showtimesNoLocationError Man-in-the-Middle App Action: willUpdateShowtimes Action: showtimesNoLocation Error

46 46 Vulnerability: Spoofing

47 47 Vulnerability: Permission re-Delegation r Permission re-delegation occurs when an application without a permission gains additional privileges through another application

48 48 Permission System API Malware Deputy toggleWifi() Permission System toggleWifi()

49 49 Permission Redelegation Malware API Deputy Malware toggleWifi() pressButton(0) Permission System

50 Permission Redelegation: Reality Check 50 r Analyzed manifests of 5 system applications r Built attacks using 5 of the 16 system apps r Found 15 attacks in the 5 applications

51 More Examples of Attack r DeskClock: m Start an internal service m Tell it to infinitely vibrate with a WAKE_LOCK on r Phone: m Trigger the “phone call answered” message receiver m Phone call will be silenced, vibrate cancelled r More details see schedule page links 51

52 More Info on IPC r Intent is a high level abstraction r For more details on implementation of Intent, see a set of slides on binder 52 Binder AIDL Intent More abstract

53 Progress So Far r Issue (responsiveness): slow UI is a sin m Solution: event listener gives tasks to background thread(s) m Issue: Background threads may need to update UI m Solution: Handler/AsyncTask so that one thread can delegate tasks to to another thread r Issue (composability): reusability is highly desired m Solution: Intent 53

54 Problem: Accessing Data in Cloud r A typical setting is that a device accesses data in the cloud r Challenge: How do you keep data on a device fresh? 54

55 Solution 1: Polling r Simple to implement r Device periodically asks server for new data/update r Appropriate for content that changes constantly m Stock Quotes, News Headlines  Problems? 55

56 Impact of Polling on Battery r Baseline: ~5-8 mA r Network: ~180-200 mA m Tx more expensive than Rx r Assume radio stays on for 10 sec. m Energy per poll: ~0.50 mAh m 5 min frequency: ~144 mAh / day r Droid 2 total battery: 1400 mAh 56 Source: Android development team at Google

57 Solution 2: Push Notification r Design issue: Who to push to client device? m Option 1: each app does it individually m Option 2: a shared push service 57

58 Push Service r A single persistent connection from device to Cloud provider r Multiple application providers push to a cloud provider r Cloud provider pushes to a device using the persistent connection r Two examples m Apple Push Notification Service (APNS) m Google Cloud Messaging (GCM) 58

59 Design Issues of a Push Service r How to do authorization? m Do not want to allow arbitrary app to push to a device r What to push? m Option 1: Just push signal (data available) and then app fetches from app server or push data m Option 2: push real data 59

60 Apple Push Notification Service 60 r iOS device maintains a persistent TCP connection to a Apple Push Notification Server(APNS) A push notification from a provider to a client application Multi-providers to multiple devices

61 Apple Push Notification: Device Token 61 r Device token is analogous to a phone number m Contains information that enables APNs to locate the device m Client app needs to provide the token to its provider m Device token should be requested and passed to providers every time your application launches

62 Apple Push Notification Data r Each push notification carries a payload m 256 bytes maximum m Best effort delivery r App provider provides a JSON dictionary object, which contains another dictionary identified by the key aps r aps specifies the following actions An alert message to display to the user A number to badge the application icon with A sound to play 62

63 APNS Example: Client 63 1. - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 2. { 3. // Let the device know we want to receive push notifications 4. [[UIApplication sharedApplication] registerForRemoteNotificationTypes: 5. (UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)]; 6. 7. return YES; 8. } 9. - (void)application:(UIApplication*)application didReceiveRemoteNotification:(NSDictionary*)userInfo 10. {//userInfo contains the notification 11. NSLog(@"Received notification: %@", userInfo); 12. } 13. - (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken 14. { 15. NSLog(@"My token is: %@", deviceToken); 16. }

64 APNS Example: Server 64 1. $devicetoken ='f05571e4be60a4e11524d76e4366862128f430522fb470c46fc6810fffb07af7’; 2. // Put your private key's passphrase here: 3. $passphrase = 'PushChat'; 4. // Put your alert message here: 5. $message = ’CS434: my first push notification!'; 1. $ctx = stream_context_create(); 2. Stream_context_set_option($ctx, 'ssl', 'local_cert', 'ck.pem'); 3. stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase); 4. // Open a connection to the APNS server 5. $fp = stream_socket_client( 6. 'ssl://gateway.sandbox.push.apple.com:2195', $err, 7. $errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx); 8. if (!$fp) 9. exit("Failed to connect: $err $errstr". PHP_EOL); 10. echo 'Connected to APNS'. PHP_EOL;

65 APNS Example: Server (cont’) 65 16. // Create the payload body 17. $body['aps'] = array( 18. 'alert' => $message, 19. 'sound' => 'default' 20. ); 21. // Encode the payload as JSON 22. $payload = json_encode($body); 23. // Build the binary notification 24. $msg = chr(0). pack('n', 32). pack('H*', $deviceToken). pack('n', strlen($payload)). $payload; 25. // Send it to the server 26. $result = fwrite($fp, $msg, strlen($msg)); 27. if (!$result) 28. echo 'Message not delivered'. PHP_EOL; 29. else 30. echo 'Message successfully delivered'. PHP_EOL; 31. // Close the connection to the server 32. fclose($fp);

66 Google Cloud Messaging r Very similar to APNS 66 GCM Servers See http://developer.android.com/guide/google/gcm/gs.html for detailed steps

67 GCM Flow r Enabling cloud to device messaging m App (on device) registers with Google, gets registration ID m App sends registration ID to its App Server r Per message m App Server sends (authenticated) message to Google m Google sends message to device, which sends to registered app r Disabling cloud to device messaging m App can unregister ID, e.g., when user no longer wants push 67

68 GCM Flow r Enabling cloud to device messaging m App (on device) registers with Google, gets registration ID 68 public class MyActivity extends Activity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); GCMRegistrar.checkDevice(this); GCMRegistrar.checkManifest(this); final String regId = GCMRegistrar.getRegistrationId(this); if (regId.equals("")) { GCMRegistrar.register(this, SENDER_ID); } else { Log.v(TAG, "Already registered"); } … } http://developer.android.com/guide/ google/gcm/gs.html

69 GCM Flow r Enabling cloud to device messaging m App (on device) registers with Google, gets registration ID m App sends registration ID to its App Server r Per message m App Server sends (authenticated) message to Google m Google sends message to device r Disabling cloud to device messaging m App can unregister ID, e.g., when user no longer wants push 69

70 Android Code: Registration to C2DM // Use the Intent API to get a registration ID // Registration ID is compartmentalized per app/device Intent regIntent = new Intent(“com.google.android.c2dm.intent.REGISTER”); // Identify your app regIntent.putExtra(“app”, PendingIntent.getBroadcast(this, 0, new Intent(), 0); // Identify role account server will use to send regIntent.putExtra(“sender”, emailOfSender); // Start the registration process startService(regIntent); 70

71 Receiving Registration ID 71 // Registration ID received via an Intent public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (“…REGISTRATION”.equals(action)) { handleRegistration(context, intent); } private void handleRegistration(Context context, Intent intent){ String id = intent.getExtra(“registration_id”); if ((intent.getExtra(“error”) != null) { // Registration failed. Try again later, with backoff. } else if (id != null) { // Send the registration ID to the app’s server. // Be sure to do this in a separate thread. }

72 Receiving Registration ID r App receives the ID as an Intent m com.google.android.c2dm.intent.REGISTRATION r App should send this ID to its server r Service may issue new registration ID at any time r App will receive REGISTRATION Intent broadcast r App must update server with new ID 72


Download ppt "1 Mobile Software Development Framework: Android IPC; Mobile Push Notification 10/16/2012 Y. Richard Yang."

Similar presentations


Ads by Google