@@ -18,6 +18,14 @@ public class LicenseChecker {
1818 private static final String RESULT_LISTENER_DESCRIPTOR = "com.android.vending.licensing.ILicenseResultListener" ;
1919 private static final int TRANSACTION_CHECK_LICENSE = IBinder .FIRST_CALL_TRANSACTION ;
2020
21+ // Error codes for better diagnostics
22+ private static final int ERROR_GENERIC = -1 ;
23+ private static final int ERROR_BIND_FAILED = -5 ;
24+ private static final int ERROR_NO_BINDER = -3 ;
25+ private static final int ERROR_TRANSACT_FAILED = -2 ;
26+ private static final int ERROR_REMOTE_EXCEPTION = -4 ;
27+ private static final int ERROR_BINDER_DIED = -6 ;
28+
2129 private final Context mContext ;
2230 private final LicenseRawCallback mCallback ;
2331 private final ILogger logger ;
@@ -47,6 +55,11 @@ public synchronized void checkAccess() {
4755 serviceIntent .setPackage (GOOGLE_PLAY_PACKAGE );
4856 boolean isBind = mContext .bindService (serviceIntent , mServiceConnection , Context .BIND_AUTO_CREATE );
4957 logger .debug ("LVL bindService result: " + isBind );
58+
59+ if (!isBind ) {
60+ logger .error ("LVL failed to bind licensing service" );
61+ mCallback .onError (ERROR_BIND_FAILED );
62+ }
5063 }
5164
5265 public void onDestroy () {
@@ -55,6 +68,8 @@ public void onDestroy() {
5568 mContext .unbindService (mServiceConnection );
5669 mBound = false ;
5770 }
71+ // Ensure binder reference is cleared even if unbind fails
72+ mServiceBinder = null ;
5873 }
5974
6075 private final ServiceConnection mServiceConnection = new ServiceConnection () {
@@ -64,6 +79,18 @@ public void onServiceConnected(ComponentName name, IBinder service) {
6479 mServiceBinder = service ;
6580 mBound = true ;
6681 retryCount = 0 ;
82+
83+ // Detect binder death proactively
84+ try {
85+ mServiceBinder .linkToDeath (() -> {
86+ logger .error ("LVL binder died unexpectedly" );
87+ mCallback .onError (ERROR_BINDER_DIED );
88+ onDestroy ();
89+ }, 0 );
90+ } catch (RemoteException e ) {
91+ logger .error ("LVL failed to link binder death recipient" , e );
92+ }
93+
6794 executeLicenseCheck ();
6895 }
6996
@@ -79,7 +106,7 @@ private void executeLicenseCheck() {
79106 try {
80107 if (mServiceBinder == null ) {
81108 logger .error ("LVL binder unavailable for license check" );
82- mCallback .onError (- 1 );
109+ mCallback .onError (ERROR_NO_BINDER );
83110 return ;
84111 }
85112
@@ -102,17 +129,17 @@ private void executeLicenseCheck() {
102129 logger .debug ("LVL binder transact sent (code " + TRANSACTION_CHECK_LICENSE + "): " + transacted );
103130 if (!transacted ) {
104131 logger .error ("LVL binder transact failed to enqueue" );
105- mCallback .onError (- 1 );
132+ mCallback .onError (ERROR_TRANSACT_FAILED );
106133 }
107134 } finally {
108135 data .recycle ();
109136 }
110137 } catch (RemoteException e ) {
111138 logger .error ("LVL remote exception during license check: " , e );
112- mCallback .onError (- 1 );
139+ mCallback .onError (ERROR_REMOTE_EXCEPTION );
113140 } catch (Exception e ) {
114141 logger .error ("LVL license check failed: " , e );
115- mCallback .onError (- 1 );
142+ mCallback .onError (ERROR_GENERIC );
116143 }
117144 }
118145
@@ -156,7 +183,8 @@ protected boolean onTransact(int code, Parcel data, Parcel reply, int flags) thr
156183 return true ;
157184 } catch (Exception ex ) {
158185 logger .error ("LVL failed to process license response: " , ex );
159- mCallback .onError (-1 );
186+ mCallback .onError (ERROR_GENERIC );
187+ onDestroy ();
160188 return true ;
161189 }
162190 }
@@ -178,5 +206,4 @@ public static long generateNonce(long timestamp) {
178206 // Shift timestamp to occupy bits 8–63, reserve LSB for flags/version
179207 return (reducedTimestamp << 8 ) | 0x01 ;
180208 }
181-
182209}
0 commit comments