1 // Copyright 2019 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 package org.chromium.chrome.browser.customtabs; 6 7 import static org.chromium.chrome.browser.dependency_injection.ChromeCommonQualifiers.APP_CONTEXT; 8 9 import android.content.Context; 10 import android.graphics.Bitmap; 11 import android.net.Uri; 12 import android.os.Bundle; 13 14 import androidx.annotation.WorkerThread; 15 import androidx.browser.customtabs.CustomTabsService; 16 import androidx.browser.customtabs.CustomTabsSessionToken; 17 18 import org.chromium.base.FileUtils; 19 import org.chromium.base.Log; 20 import org.chromium.chrome.browser.browserservices.ui.splashscreen.trustedwebactivity.SplashImageHolder; 21 22 import javax.inject.Inject; 23 import javax.inject.Named; 24 import javax.inject.Singleton; 25 26 import dagger.Lazy; 27 28 /** 29 * Processes the files received via Custom Tab connection from client apps. 30 */ 31 @Singleton 32 public class CustomTabsClientFileProcessor { 33 34 private static final String TAG = "CustomTabFiles"; 35 36 private final Context mContext; 37 private final Lazy<SplashImageHolder> mTwaSplashImageHolder; 38 private boolean mTwaSplashImageHolderCreated; 39 40 @Inject CustomTabsClientFileProcessor(@amedAPP_CONTEXT) Context context, Lazy<SplashImageHolder> twaSplashImageHolder)41 public CustomTabsClientFileProcessor(@Named(APP_CONTEXT) Context context, 42 Lazy<SplashImageHolder> twaSplashImageHolder) { 43 mTwaSplashImageHolder = twaSplashImageHolder; 44 mContext = context; 45 } 46 47 /** 48 * Processes the file located at given URI. 49 * @return {@code true} if successful. 50 */ 51 @WorkerThread processFile(CustomTabsSessionToken session, Uri uri, int purpose, Bundle extras)52 public boolean processFile(CustomTabsSessionToken session, Uri uri, 53 int purpose, Bundle extras) { 54 if (uri == null) { 55 Log.w(TAG, "Received a null uri"); 56 return false; 57 } 58 switch (purpose) { 59 case CustomTabsService.FILE_PURPOSE_TRUSTED_WEB_ACTIVITY_SPLASH_IMAGE: 60 return receiveTwaSplashImage(session, uri); 61 } 62 Log.w(TAG, "Unknown FilePurpose " + purpose); 63 return false; 64 } 65 receiveTwaSplashImage(CustomTabsSessionToken sessionToken, Uri uri)66 private boolean receiveTwaSplashImage(CustomTabsSessionToken sessionToken, Uri uri) { 67 Bitmap bitmap = FileUtils.queryBitmapFromContentProvider(mContext, uri); 68 if (bitmap == null) return false; 69 70 mTwaSplashImageHolder.get().putImage(sessionToken, bitmap); 71 mTwaSplashImageHolderCreated = true; 72 return true; 73 } 74 75 /** 76 * Cleans up files associated with the session that has been disconnected. 77 */ onSessionDisconnected(CustomTabsSessionToken session)78 public void onSessionDisconnected(CustomTabsSessionToken session) { 79 if (mTwaSplashImageHolderCreated) { 80 // If the image still hasn't been claimed, delete it. 81 mTwaSplashImageHolder.get().takeImage(session); 82 } 83 } 84 } 85