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