108889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal/* 2ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * Copyright 2018 The Android Open Source Project 308889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal * 408889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal * Licensed under the Apache License, Version 2.0 (the "License"); 508889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal * you may not use this file except in compliance with the License. 608889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal * You may obtain a copy of the License at 708889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal * 808889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal * http://www.apache.org/licenses/LICENSE-2.0 908889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal * 1008889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal * Unless required by applicable law or agreed to in writing, software 1108889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal * distributed under the License is distributed on an "AS IS" BASIS, 1208889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1308889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal * See the License for the specific language governing permissions and 1408889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal * limitations under the License. 1508889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal */ 1608889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal 17ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikaspackage androidx.browser.customtabs; 1808889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal 19c5c0045de7c8848144a570665e0d3c950816f314Yusuf Ozuysalimport android.content.Intent; 2093745fc87a8e47b63731b5cb7eba57621b007404Benoît Lizéimport android.net.Uri; 2108889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysalimport android.os.Bundle; 2208889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysalimport android.os.IBinder; 2308889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysalimport android.os.RemoteException; 24ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport android.support.customtabs.ICustomTabsCallback; 2508889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysalimport android.util.Log; 2608889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal 2788f23f4c3c9d439cf8b300195962cb9a4e5f3165Aurimas Liutikasimport androidx.annotation.NonNull; 2888f23f4c3c9d439cf8b300195962cb9a4e5f3165Aurimas Liutikasimport androidx.core.app.BundleCompat; 2988f23f4c3c9d439cf8b300195962cb9a4e5f3165Aurimas Liutikas 3008889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal/** 3108889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal * Wrapper class that can be used as a unique identifier for a session. Also contains an accessor 3208889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal * for the {@link CustomTabsCallback} for the session if there was any. 3308889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal */ 3408889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysalpublic class CustomTabsSessionToken { 3508889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal private static final String TAG = "CustomTabsSessionToken"; 3608889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal private final ICustomTabsCallback mCallbackBinder; 3708889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal private final CustomTabsCallback mCallback; 3808889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal 39d3a61406d0204250d60c140d435f6848771bc740Yusuf Ozuysal /* package */ static class MockCallback extends ICustomTabsCallback.Stub { 40d3a61406d0204250d60c140d435f6848771bc740Yusuf Ozuysal @Override 41d3a61406d0204250d60c140d435f6848771bc740Yusuf Ozuysal public void onNavigationEvent(int navigationEvent, Bundle extras) {} 42d3a61406d0204250d60c140d435f6848771bc740Yusuf Ozuysal 43d3a61406d0204250d60c140d435f6848771bc740Yusuf Ozuysal @Override 44d3a61406d0204250d60c140d435f6848771bc740Yusuf Ozuysal public void extraCallback(String callbackName, Bundle args) {} 45d3a61406d0204250d60c140d435f6848771bc740Yusuf Ozuysal 46d3a61406d0204250d60c140d435f6848771bc740Yusuf Ozuysal @Override 47d3a61406d0204250d60c140d435f6848771bc740Yusuf Ozuysal public void onMessageChannelReady(Bundle extras) {} 48d3a61406d0204250d60c140d435f6848771bc740Yusuf Ozuysal 49d3a61406d0204250d60c140d435f6848771bc740Yusuf Ozuysal @Override 50d3a61406d0204250d60c140d435f6848771bc740Yusuf Ozuysal public void onPostMessage(String message, Bundle extras) {} 51d3a61406d0204250d60c140d435f6848771bc740Yusuf Ozuysal 52d3a61406d0204250d60c140d435f6848771bc740Yusuf Ozuysal @Override 53ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas public void onRelationshipValidationResult(@CustomTabsService.Relation int relation, Uri requestedOrigin, 54d3a61406d0204250d60c140d435f6848771bc740Yusuf Ozuysal boolean result, Bundle extras) {} 55d3a61406d0204250d60c140d435f6848771bc740Yusuf Ozuysal 56d3a61406d0204250d60c140d435f6848771bc740Yusuf Ozuysal @Override 57d3a61406d0204250d60c140d435f6848771bc740Yusuf Ozuysal public IBinder asBinder() { 58d3a61406d0204250d60c140d435f6848771bc740Yusuf Ozuysal return this; 59d3a61406d0204250d60c140d435f6848771bc740Yusuf Ozuysal } 60d3a61406d0204250d60c140d435f6848771bc740Yusuf Ozuysal } 61d3a61406d0204250d60c140d435f6848771bc740Yusuf Ozuysal 62c5c0045de7c8848144a570665e0d3c950816f314Yusuf Ozuysal /** 63c5c0045de7c8848144a570665e0d3c950816f314Yusuf Ozuysal * Obtain a {@link CustomTabsSessionToken} from an intent. See {@link CustomTabsIntent.Builder} 64c5c0045de7c8848144a570665e0d3c950816f314Yusuf Ozuysal * for ways to generate an intent for custom tabs. 65c5c0045de7c8848144a570665e0d3c950816f314Yusuf Ozuysal * @param intent The intent to generate the token from. This has to include an extra for 66c5c0045de7c8848144a570665e0d3c950816f314Yusuf Ozuysal * {@link CustomTabsIntent#EXTRA_SESSION}. 67c5c0045de7c8848144a570665e0d3c950816f314Yusuf Ozuysal * @return The token that was generated. 68c5c0045de7c8848144a570665e0d3c950816f314Yusuf Ozuysal */ 69c5c0045de7c8848144a570665e0d3c950816f314Yusuf Ozuysal public static CustomTabsSessionToken getSessionTokenFromIntent(Intent intent) { 70c5c0045de7c8848144a570665e0d3c950816f314Yusuf Ozuysal Bundle b = intent.getExtras(); 71c5c0045de7c8848144a570665e0d3c950816f314Yusuf Ozuysal IBinder binder = BundleCompat.getBinder(b, CustomTabsIntent.EXTRA_SESSION); 72c5c0045de7c8848144a570665e0d3c950816f314Yusuf Ozuysal if (binder == null) return null; 73c5c0045de7c8848144a570665e0d3c950816f314Yusuf Ozuysal return new CustomTabsSessionToken(ICustomTabsCallback.Stub.asInterface(binder)); 74c5c0045de7c8848144a570665e0d3c950816f314Yusuf Ozuysal } 75c5c0045de7c8848144a570665e0d3c950816f314Yusuf Ozuysal 76d3a61406d0204250d60c140d435f6848771bc740Yusuf Ozuysal /** 77d3a61406d0204250d60c140d435f6848771bc740Yusuf Ozuysal * Provides browsers a way to generate a mock {@link CustomTabsSessionToken} for testing 78d3a61406d0204250d60c140d435f6848771bc740Yusuf Ozuysal * purposes. 79d3a61406d0204250d60c140d435f6848771bc740Yusuf Ozuysal * 80d3a61406d0204250d60c140d435f6848771bc740Yusuf Ozuysal * @return A mock token with no functionality. 81d3a61406d0204250d60c140d435f6848771bc740Yusuf Ozuysal */ 82d3a61406d0204250d60c140d435f6848771bc740Yusuf Ozuysal @NonNull 83d3a61406d0204250d60c140d435f6848771bc740Yusuf Ozuysal public static CustomTabsSessionToken createMockSessionTokenForTesting() { 84d3a61406d0204250d60c140d435f6848771bc740Yusuf Ozuysal return new CustomTabsSessionToken(new MockCallback()); 85d3a61406d0204250d60c140d435f6848771bc740Yusuf Ozuysal } 86d3a61406d0204250d60c140d435f6848771bc740Yusuf Ozuysal 8708889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal CustomTabsSessionToken(ICustomTabsCallback callbackBinder) { 8808889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal mCallbackBinder = callbackBinder; 8908889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal mCallback = new CustomTabsCallback() { 9008889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal 9108889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal @Override 9208889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal public void onNavigationEvent(int navigationEvent, Bundle extras) { 9308889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal try { 9408889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal mCallbackBinder.onNavigationEvent(navigationEvent, extras); 9508889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal } catch (RemoteException e) { 9608889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal Log.e(TAG, "RemoteException during ICustomTabsCallback transaction"); 9708889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal } 9808889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal } 99914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal 100914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal @Override 101914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal public void extraCallback(String callbackName, Bundle args) { 102914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal try { 103914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal mCallbackBinder.extraCallback(callbackName, args); 104914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal } catch (RemoteException e) { 105914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal Log.e(TAG, "RemoteException during ICustomTabsCallback transaction"); 106914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal } 107914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal } 108914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal 109914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal @Override 110914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal public void onMessageChannelReady(Bundle extras) { 111914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal try { 112914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal mCallbackBinder.onMessageChannelReady(extras); 113914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal } catch (RemoteException e) { 114914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal Log.e(TAG, "RemoteException during ICustomTabsCallback transaction"); 115914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal } 116914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal } 117914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal 118914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal @Override 119914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal public void onPostMessage(String message, Bundle extras) { 120914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal try { 121914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal mCallbackBinder.onPostMessage(message, extras); 122914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal } catch (RemoteException e) { 123914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal Log.e(TAG, "RemoteException during ICustomTabsCallback transaction"); 124914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal } 125914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal } 12693745fc87a8e47b63731b5cb7eba57621b007404Benoît Lizé 12793745fc87a8e47b63731b5cb7eba57621b007404Benoît Lizé @Override 128ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas public void onRelationshipValidationResult(@CustomTabsService.Relation int relation, Uri origin, 12993745fc87a8e47b63731b5cb7eba57621b007404Benoît Lizé boolean result, Bundle extras) { 13093745fc87a8e47b63731b5cb7eba57621b007404Benoît Lizé try { 13193745fc87a8e47b63731b5cb7eba57621b007404Benoît Lizé mCallbackBinder.onRelationshipValidationResult( 13293745fc87a8e47b63731b5cb7eba57621b007404Benoît Lizé relation, origin, result, extras); 13393745fc87a8e47b63731b5cb7eba57621b007404Benoît Lizé } catch (RemoteException e) { 13493745fc87a8e47b63731b5cb7eba57621b007404Benoît Lizé Log.e(TAG, "RemoteException during ICustomTabsCallback transaction"); 13593745fc87a8e47b63731b5cb7eba57621b007404Benoît Lizé } 13693745fc87a8e47b63731b5cb7eba57621b007404Benoît Lizé } 13793745fc87a8e47b63731b5cb7eba57621b007404Benoît Lizé 13808889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal }; 13908889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal } 14008889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal 14108889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal IBinder getCallbackBinder() { 14208889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal return mCallbackBinder.asBinder(); 14308889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal } 14408889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal 14508889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal @Override 14697ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize public int hashCode() { 14797ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize return getCallbackBinder().hashCode(); 14897ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize } 14997ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize 15097ee4f3f353309991efd3ceca369548b485e9a5fBenoit Lize @Override 15108889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal public boolean equals(Object o) { 15208889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal if (!(o instanceof CustomTabsSessionToken)) return false; 15308889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal CustomTabsSessionToken token = (CustomTabsSessionToken) o; 15408889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal return token.getCallbackBinder().equals(mCallbackBinder.asBinder()); 15508889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal } 15608889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal 15708889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal /** 15808889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal * @return {@link CustomTabsCallback} corresponding to this session if there was any non-null 15908889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal * callbacks passed by the client. 16008889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal */ 16108889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal public CustomTabsCallback getCallback() { 16208889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal return mCallback; 16308889acbc842c73b64f94a761910154d9d42ee4cYusuf Ozuysal } 164914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal 165914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal /** 166914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal * @return Whether this token is associated with the given session. 167914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal */ 168914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal public boolean isAssociatedWith(CustomTabsSession session) { 169914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal return session.getBinder().equals(mCallbackBinder); 170914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal } 171914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal} 172