private static Context getContext() { // Using the global application context is probably ok. // The DisplayManager API observers all display updates, so in theory it should not matter // which context is used to obtain it. If this turns out not to be true in practice, it's // possible register from all context used though quite complex. return ContextUtils.getApplicationContext(); }
private static void tryObtainingDataDirLockOrDie() { StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); StrictMode.allowThreadDiskWrites(); try { String dataPath = PathUtils.getDataDirectory(ContextUtils.getApplicationContext()); File lockFile = new File(dataPath, EXCLUSIVE_LOCK_FILE); boolean success = false; try { // Note that the file is not closed intentionally. RandomAccessFile file = new RandomAccessFile(lockFile, "rw"); sExclusiveFileLock = file.getChannel().tryLock(); success = sExclusiveFileLock != null; } catch (IOException e) { Log.w(TAG, "Failed to create lock file " + lockFile, e); } if (!success) { Log.w( TAG, "The app may have another WebView opened in a separate process. " + "This is not recommended and may stop working in future versions."); } } finally { StrictMode.setThreadPolicy(oldPolicy); } }
/** * Enables the data reduction proxy, records uma, and shows a confirmation toast. * * @param isPrimaryButton Whether the primary infobar button was clicked. * @param context An Android context. */ @CalledByNative private static void accept() { Context context = ContextUtils.getApplicationContext(); DataReductionProxyUma.dataReductionProxyUIAction(DataReductionProxyUma.ACTION_INFOBAR_ENABLED); DataReductionProxySettings.getInstance().setDataReductionProxyEnabled(context, true); Toast.makeText( context, context.getString(R.string.data_reduction_enabled_toast), Toast.LENGTH_LONG) .show(); }
/** * Check the cached value to figure out if the feature is enabled. We have to use the cached value * because native library may not yet been loaded. * * @return Whether the feature is enabled. */ private static boolean isEnabledInPrefs() { // Will go away once the feature is enabled for everyone by default. StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); try { return ChromePreferenceManager.getInstance(ContextUtils.getApplicationContext()) .getCachedWebApkRuntimeEnabled(); } finally { StrictMode.setThreadPolicy(oldPolicy); } }
/** * Loads the native library, and performs basic static construction of objects needed to run * webview in this process. Does not create threads; safe to call from zygote. Note: it is up to * the caller to ensure this is only called once. */ public static void loadLibrary() { Context appContext = ContextUtils.getApplicationContext(); PathUtils.setPrivateDataDirectorySuffix(PRIVATE_DATA_DIRECTORY_SUFFIX, appContext); try { LibraryLoader libraryLoader = LibraryLoader.get(LibraryProcessType.PROCESS_WEBVIEW); libraryLoader.loadNow(appContext); // Switch the command line implementation from Java to native. // It's okay for the WebView to do this before initialization because we have // setup the JNI bindings by this point. libraryLoader.switchCommandLineForWebView(); } catch (ProcessInitException e) { throw new RuntimeException("Cannot load WebView", e); } }
/** * Once native is loaded we can consult the command-line (set via about:flags) and also finch * state to see if we should enable WebAPKs. */ public static void cacheEnabledStateForNextLaunch() { boolean wasEnabled = isEnabledInPrefs(); CommandLine instance = CommandLine.getInstance(); String experiment = FieldTrialList.findFullName(WEBAPK_DISABLE_EXPERIMENT_NAME); boolean isEnabled = (!WEBAPK_RUNTIME_DISABLED.equals(experiment) && instance.hasSwitch(ChromeSwitches.ENABLE_WEBAPK)); if (isEnabled != wasEnabled) { Log.d(TAG, "WebApk setting changed (%s => %s)", wasEnabled, isEnabled); ChromePreferenceManager.getInstance(ContextUtils.getApplicationContext()) .setCachedWebApkRuntimeEnabled(isEnabled); } }
/** * Displays the download manager UI. Note the UI is different on tablets and on phones. * * @return Whether the UI was shown. */ public static boolean showDownloadManager(@Nullable Activity activity, @Nullable Tab tab) { if (!isDownloadHomeEnabled()) return false; // Figure out what tab was last being viewed by the user. if (activity == null) activity = ApplicationStatus.getLastTrackedFocusedActivity(); if (tab == null && activity instanceof ChromeTabbedActivity) { tab = ((ChromeTabbedActivity) activity).getActivityTab(); } Context appContext = ContextUtils.getApplicationContext(); if (DeviceFormFactor.isTablet(appContext)) { // Download Home shows up as a tab on tablets. LoadUrlParams params = new LoadUrlParams(UrlConstants.DOWNLOADS_URL); if (tab == null || !tab.isInitialized()) { // Open a new tab, which pops Chrome into the foreground. TabDelegate delegate = new TabDelegate(false); delegate.createNewTab(params, TabLaunchType.FROM_CHROME_UI, null); } else { // Download Home shows up inside an existing tab, but only if the last Activity was // the ChromeTabbedActivity. tab.loadUrl(params); // Bring Chrome to the foreground, if possible. Intent intent = Tab.createBringTabToFrontIntent(tab.getId()); if (intent != null) { intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); IntentUtils.safeStartActivity(appContext, intent); } } } else { // Download Home shows up as a new Activity on phones. Intent intent = new Intent(); intent.setClass(appContext, DownloadActivity.class); if (tab != null) intent.putExtra(EXTRA_IS_OFF_THE_RECORD, tab.isIncognito()); if (activity == null) { // Stands alone in its own task. intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); appContext.startActivity(intent); } else { // Sits on top of another Activity. intent.putExtra(IntentHandler.EXTRA_PARENT_COMPONENT, activity.getComponentName()); activity.startActivity(intent); } } return true; }
@Override public void activateContents() { String startUrl = mActivity.getWebappInfo().uri().toString(); // Create an Intent that will be fired toward the WebappLauncherActivity, which in turn // will fire an Intent to launch the correct WebappActivity. On L+ this could probably // be changed to call AppTask.moveToFront(), but for backwards compatibility we relaunch // it the hard way. Intent intent = new Intent(); intent.setAction(WebappLauncherActivity.ACTION_START_WEBAPP); intent.setPackage(mActivity.getPackageName()); mActivity.getWebappInfo().setWebappIntentExtras(intent); intent.putExtra(ShortcutHelper.EXTRA_MAC, ShortcutHelper.getEncodedMac(mActivity, startUrl)); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); ContextUtils.getApplicationContext().startActivity(intent); }
/** * Creates an Intent that allows viewing the given file in an internal media viewer. * * @param fileUri URI pointing at the file, ideally in file:// form. * @param shareUri URI pointing at the file, ideally in content:// form. * @param mimeType MIME type of the file. * @return Intent that can be fired to open the file. */ public static Intent getMediaViewerIntentForDownloadItem( Uri fileUri, Uri shareUri, String mimeType) { Context context = ContextUtils.getApplicationContext(); Intent viewIntent = createViewIntentForDownloadItem(fileUri, mimeType); Bitmap closeIcon = BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_arrow_back_white_24dp); Bitmap shareIcon = BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_share_white_24dp); CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder(); builder.setToolbarColor(Color.BLACK); builder.setCloseButtonIcon(closeIcon); builder.setShowTitle(true); // Create a PendingIntent that can be used to view the file externally. // TODO(dfalcantara): Check if this is problematic in multi-window mode, where two // different viewers could be visible at the same time. Intent chooserIntent = Intent.createChooser(viewIntent, null); chooserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); String openWithStr = context.getString(R.string.download_manager_open_with); PendingIntent pendingViewIntent = PendingIntent.getActivity(context, 0, chooserIntent, PendingIntent.FLAG_CANCEL_CURRENT); builder.addMenuItem(openWithStr, pendingViewIntent); // Create a PendingIntent that shares the file with external apps. PendingIntent pendingShareIntent = PendingIntent.getActivity(context, 0, createShareIntent(shareUri, mimeType), 0); builder.setActionButton(shareIcon, context.getString(R.string.share), pendingShareIntent, true); // Build up the Intent further. Intent intent = builder.build().intent; intent.setPackage(context.getPackageName()); intent.setData(fileUri); intent.putExtra(CustomTabIntentDataProvider.EXTRA_IS_MEDIA_VIEWER, true); intent.putExtra(Browser.EXTRA_APPLICATION_ID, context.getPackageName()); IntentHandler.addTrustedIntentExtras(intent, context); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setClass(context, CustomTabActivity.class); return intent; }
/** * Returns a URI that points at the file. * * @param file File to get a URI for. * @return URI that points at that file, either as a content:// URI or a file:// URI. */ public static Uri getUriForItem(File file) { Uri uri = null; // #getContentUriFromFile causes a disk read when it calls into FileProvider#getUriForFile. // Obtaining a content URI is on the critical path for creating a share intent after the // user taps on the share button, so even if we were to run this method on a background // thread we would have to wait. As it depends on user-selected items, we cannot // know/preload which URIs we need until the user presses share. StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); try { // Try to obtain a content:// URI, which is preferred to a file:// URI so that // receiving apps don't attempt to determine the file's mime type (which often fails). uri = ContentUriUtils.getContentUriFromFile(ContextUtils.getApplicationContext(), file); } catch (IllegalArgumentException e) { Log.e(TAG, "Could not create content uri: " + e); } StrictMode.setThreadPolicy(oldPolicy); if (uri == null) uri = Uri.fromFile(file); return uri; }
private DeferredStartupHandler() { mAppContext = ContextUtils.getApplicationContext(); mDeferredTasks = new LinkedList<>(); }
private DeferredStartupHandler() { mAppContext = ContextUtils.getApplicationContext(); mLocaleManager = ((ChromeApplication) mAppContext).createLocaleManager(); }
/** * Initializes a new {@link CastSessionImpl} instance. * * @param apiClient The Google Play Services client used to create the session. * @param sessionId The session identifier to use with the Cast SDK. * @param origin The origin of the frame requesting the route. * @param tabId The id of the tab containing the frame requesting the route. * @param isIncognito Whether the route is beging requested from an Incognito profile. * @param source The {@link MediaSource} corresponding to this session. * @param routeProvider The {@link CastMediaRouteProvider} instance managing this session. */ public CastSessionImpl( GoogleApiClient apiClient, String sessionId, ApplicationMetadata metadata, String applicationStatus, CastDevice castDevice, String origin, int tabId, boolean isIncognito, MediaSource source, CastMediaRouteProvider routeProvider) { mSessionId = sessionId; mRouteProvider = routeProvider; mApiClient = apiClient; mSource = source; mApplicationMetadata = metadata; mApplicationStatus = applicationStatus; mCastDevice = castDevice; mMessageHandler = mRouteProvider.getMessageHandler(); mMessageChannel = new CastMessagingChannel(this); updateNamespaces(); final Context context = ContextUtils.getApplicationContext(); if (mNamespaces.contains(CastMessageHandler.MEDIA_NAMESPACE)) { mMediaPlayer = new RemoteMediaPlayer(); mMediaPlayer.setOnStatusUpdatedListener( new RemoteMediaPlayer.OnStatusUpdatedListener() { @Override public void onStatusUpdated() { MediaStatus mediaStatus = mMediaPlayer.getMediaStatus(); if (mediaStatus == null) return; int playerState = mediaStatus.getPlayerState(); if (playerState == MediaStatus.PLAYER_STATE_PAUSED || playerState == MediaStatus.PLAYER_STATE_PLAYING) { mNotificationBuilder.setPaused(playerState != MediaStatus.PLAYER_STATE_PLAYING); mNotificationBuilder.setActions( MediaNotificationInfo.ACTION_STOP | MediaNotificationInfo.ACTION_PLAY_PAUSE); } else { mNotificationBuilder.setActions(MediaNotificationInfo.ACTION_STOP); } MediaNotificationManager.show(context, mNotificationBuilder.build()); } }); mMediaPlayer.setOnMetadataUpdatedListener( new RemoteMediaPlayer.OnMetadataUpdatedListener() { @Override public void onMetadataUpdated() { setNotificationMetadata(mNotificationBuilder); MediaNotificationManager.show(context, mNotificationBuilder.build()); } }); } Intent contentIntent = Tab.createBringTabToFrontIntent(tabId); if (contentIntent != null) { contentIntent.putExtra( MediaNotificationUma.INTENT_EXTRA_NAME, MediaNotificationUma.SOURCE_PRESENTATION); } mNotificationBuilder = new MediaNotificationInfo.Builder() .setPaused(false) .setOrigin(origin) // TODO(avayvod): the same session might have more than one tab id. Should we track // the last foreground alive tab and update the notification with it? .setTabId(tabId) .setPrivate(isIncognito) .setActions(MediaNotificationInfo.ACTION_STOP) .setContentIntent(contentIntent) .setIcon(R.drawable.ic_notification_media_route) .setDefaultLargeIcon(R.drawable.cast_playing_square) .setId(R.id.presentation_notification) .setListener(this); setNotificationMetadata(mNotificationBuilder); MediaNotificationManager.show(context, mNotificationBuilder.build()); }