1 package io.keybase.ossifrage; 2 3 import android.content.Context; 4 import android.os.RemoteException; 5 import android.os.SystemClock; 6 import android.util.Log; 7 8 import java.util.concurrent.Executor; 9 import java.util.concurrent.Executors; 10 11 import com.android.installreferrer.api.InstallReferrerClient; 12 import com.android.installreferrer.api.InstallReferrerStateListener; 13 import com.android.installreferrer.api.ReferrerDetails; 14 15 import io.keybase.ossifrage.modules.NativeLogger; 16 import keybase.StringReceiver; 17 18 public class KBInstallReferrerListener implements keybase.NativeInstallReferrerListener, InstallReferrerStateListener { 19 20 private InstallReferrerClient mReferrerClient; 21 private keybase.StringReceiver callback; 22 private Context context; 23 private int retries; 24 private Executor executor; 25 26 private static final int max_retries = 5; 27 KBInstallReferrerListener(Context _context)28 KBInstallReferrerListener(Context _context) { 29 Log.d("KBIR", "KBInstallReferrerListener created"); 30 context = _context; 31 executor = Executors.newSingleThreadExecutor(); 32 retries = 0; 33 } 34 35 // should only be called once per object 36 @Override startInstallReferrerListener(StringReceiver cb)37 public void startInstallReferrerListener(StringReceiver cb) { 38 Log.e("KBIR", "KBInstallReferrerListener started"); 39 40 mReferrerClient = InstallReferrerClient.newBuilder(this.context).build(); 41 mReferrerClient.startConnection(this); 42 callback = cb; 43 } 44 45 @Override onInstallReferrerSetupFinished(int responseCode)46 public void onInstallReferrerSetupFinished(int responseCode) { 47 Log.e("KBIR", "KBInstallReferrerListener#onInstallReferrerSetupFinished: got code " + responseCode); 48 executor.execute(new Runnable() { 49 @Override 50 public void run() { 51 switch (responseCode) { 52 case InstallReferrerClient.InstallReferrerResponse.OK: 53 // Connection established 54 handleReferrerResponseOK(); 55 return; 56 case InstallReferrerClient.InstallReferrerResponse.SERVICE_DISCONNECTED: 57 reconnect(); 58 return; 59 case InstallReferrerClient.InstallReferrerResponse.FEATURE_NOT_SUPPORTED: 60 case InstallReferrerClient.InstallReferrerResponse.SERVICE_UNAVAILABLE: 61 case InstallReferrerClient.InstallReferrerResponse.DEVELOPER_ERROR: 62 default: 63 // other issues, can't do much here.... 64 callback.callbackWithString(""); 65 } 66 } 67 }); 68 } 69 handleReferrerResponseOK()70 private void handleReferrerResponseOK() { 71 try { 72 ReferrerDetails response = mReferrerClient.getInstallReferrer(); 73 String referrerData = response.getInstallReferrer(); 74 callback.callbackWithString(referrerData); 75 } catch (RemoteException e) { 76 Log.e("KBIR", "KBInstallReferrerListener#handleReferrerResponseOK got exception: " + e.toString()); 77 e.printStackTrace(); 78 callback.callbackWithString(""); 79 } 80 mReferrerClient.endConnection(); 81 } 82 83 // tries to reconnect up to max_retries times in case of errors reconnect()84 private void reconnect() { 85 if (retries >= max_retries) { 86 Log.e("KBIR", "KBInstallReferrerListener max reconnection attempts exceeded"); 87 callback.callbackWithString(""); 88 mReferrerClient.endConnection(); 89 return; 90 } 91 92 retries++; 93 // sleep for a bit, hopefully when we wake up the play store 94 // connection will be available. 95 SystemClock.sleep(retries * 1000); 96 Log.e("KBIR", "KBInstallReferrerListener reconnecting..."); 97 mReferrerClient.startConnection(this); 98 } 99 100 @Override onInstallReferrerServiceDisconnected()101 public void onInstallReferrerServiceDisconnected() { 102 Log.e("KBIR", "KBInstallReferrerListener#onInstallReferrerServiceDisconnected: attempting restart..."); 103 executor.execute(new Runnable() { 104 @Override 105 public void run() { 106 reconnect(); 107 } 108 }); 109 } 110 }