android.support.annotation.BinderThread#org.chromium.base.ThreadUtils源码实例Demo

下面列出了android.support.annotation.BinderThread#org.chromium.base.ThreadUtils 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。

源代码1 项目: 365browser   文件: DocumentModeAssassin.java
/** Moves the user to tabbed mode by opting them out and removing all the tasks. */
final void switchToTabbedMode() {
    ThreadUtils.assertOnUiThread();
    if (!setStage(STAGE_WRITE_TABMODEL_METADATA_DONE, STAGE_CHANGE_SETTINGS_STARTED)) return;

    // Record that the user has opted-out of document mode now that their data has been
    // safely copied to the other directory.
    Log.d(TAG, "Setting tabbed mode preference.");
    setOptedOutState(OPTED_OUT_OF_DOCUMENT_MODE);
    TabSwitcherCallout.setIsTabSwitcherCalloutNecessary(true);

    // Remove all the {@link DocumentActivity} tasks from Android's Recents list.  Users
    // viewing Recents during migration will continue to see their tabs until they exit.
    // Reselecting a migrated tab will kick the user to the launcher without crashing.
    // TODO(dfalcantara): Confirm that the different Android flavors work the same way.
    createActivityDelegate().finishAllDocumentActivities();

    // Dismiss the "Close all incognito tabs" notification.
    IncognitoNotificationManager.dismissIncognitoNotification();

    setStage(STAGE_CHANGE_SETTINGS_STARTED, STAGE_CHANGE_SETTINGS_DONE);
}
 
源代码2 项目: 365browser   文件: ThumbnailProviderImpl.java
private static LruCache<String, Pair<Bitmap, Integer>> getBitmapCache() {
    ThreadUtils.assertOnUiThread();

    LruCache<String, Pair<Bitmap, Integer>> cache =
            sBitmapCache == null ? null : sBitmapCache.get();
    if (cache != null) return cache;

    // Create a new weakly-referenced cache.
    cache = new LruCache<String, Pair<Bitmap, Integer>>(MAX_CACHE_BYTES) {
        @Override
        protected int sizeOf(String key, Pair<Bitmap, Integer> thumbnail) {
            return thumbnail == null ? 0 : thumbnail.second;
        }
    };
    sBitmapCache = new WeakReference<>(cache);
    return cache;
}
 
源代码3 项目: delion   文件: SigninManager.java
/**
 * Performs an asynchronous check to see if the user is a managed user.
 * @param callback A callback to be called with true if the user is a managed user and false
 *         otherwise.
 */
public static void isUserManaged(String email, final Callback<Boolean> callback) {
    if (nativeShouldLoadPolicyForUser(email)) {
        nativeIsUserManaged(email, callback);
    } else {
        // Although we know the result immediately, the caller may not be able to handle the
        // callback being executed during this method call. So we post the callback on the
        // looper.
        ThreadUtils.postOnUiThread(new Runnable() {
            @Override
            public void run() {
                callback.onResult(false);
            }
        });
    }
}
 
源代码4 项目: delion   文件: ConnectivityTask.java
/**
 * Retrieves the connectivity that has been collected up until this call. This method fills in
 * {@link ConnectivityCheckResult#UNKNOWN} for results that have not been retrieved yet.
 *
 * @return the {@link FeedbackData}.
 */
public FeedbackData get() {
    ThreadUtils.assertOnUiThread();
    Map<Type, Integer> result = new EnumMap<Type, Integer>(Type.class);
    // Ensure the map is filled with a result for all {@link Type}s.
    for (Type type : Type.values()) {
        if (mResult.containsKey(type)) {
            result.put(type, mResult.get(type));
        } else {
            result.put(type, ConnectivityCheckResult.UNKNOWN);
        }
    }
    long elapsedTimeMs = SystemClock.elapsedRealtime() - mStartCheckTimeMs;
    int connectionType = NetworkChangeNotifier.getInstance().getCurrentConnectionType();
    return new FeedbackData(result, mTimeoutMs, elapsedTimeMs, connectionType);
}
 
源代码5 项目: delion   文件: TtsPlatformImpl.java
protected TtsPlatformImpl(long nativeTtsPlatformImplAndroid, Context context) {
    mInitialized = false;
    mNativeTtsPlatformImplAndroid = nativeTtsPlatformImplAndroid;
    mTextToSpeech = new TextToSpeech(context, new TextToSpeech.OnInitListener() {
            @Override
            public void onInit(int status) {
                if (status == TextToSpeech.SUCCESS) {
                    ThreadUtils.runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            initialize();
                        }
                    });
                }
            }
        });
    addOnUtteranceProgressListener();
}
 
源代码6 项目: 365browser   文件: BindingManagerImpl.java
@Override
public void onTrimMemory(final int level) {
    ThreadUtils.assertOnUiThread();
    LauncherThread.post(new Runnable() {
        @Override
        public void run() {
            Log.i(TAG, "onTrimMemory: level=%d, size=%d", level, mConnections.size());
            if (mConnections.isEmpty()) {
                return;
            }
            if (level <= TRIM_MEMORY_RUNNING_MODERATE) {
                reduce(MODERATE_BINDING_LOW_REDUCE_RATIO);
            } else if (level <= TRIM_MEMORY_RUNNING_LOW) {
                reduce(MODERATE_BINDING_HIGH_REDUCE_RATIO);
            } else if (level == TRIM_MEMORY_UI_HIDDEN) {
                // This will be handled by |mDelayedClearer|.
                return;
            } else {
                removeAllConnections();
            }
        }
    });
}
 
源代码7 项目: 365browser   文件: UrlManager.java
/**
 * Register a StartupCallback to initialize the native portion of the JNI bridge.
 */
private void registerNativeInitStartupCallback() {
    ThreadUtils.postOnUiThread(new Runnable() {
        @Override
        public void run() {
            BrowserStartupController.get(LibraryProcessType.PROCESS_BROWSER)
                    .addStartupCompletedObserver(new StartupCallback() {
                        @Override
                        public void onSuccess(boolean alreadyStarted) {
                            mNativePhysicalWebDataSourceAndroid = nativeInit();
                            for (UrlInfo urlInfo : getUrls()) {
                                safeNotifyNativeListenersOnFound(urlInfo.getUrl());
                            }
                        }

                        @Override
                        public void onFailure() {
                            // Startup failed.
                        }
                    });
        }
    });
}
 
源代码8 项目: AndroidChromium   文件: CustomTabActivity.java
/**
 * Finishes the activity and removes the reference from the Android recents.
 *
 * @param reparenting true iff the activity finishes due to tab reparenting.
 */
public final void finishAndClose(boolean reparenting) {
    mIsClosing = true;
    if (!reparenting) {
        // Closing the activity destroys the renderer as well. Re-create a spare renderer some
        // time after, so that we have one ready for the next tab open. This does not increase
        // memory consumption, as the current renderer goes away. We create a renderer as a lot
        // of users open several Custom Tabs in a row. The delay is there to avoid jank in the
        // transition animation when closing the tab.
        ThreadUtils.postOnUiThreadDelayed(new Runnable() {
            @Override
            public void run() {
                WarmupManager.getInstance().createSpareWebContents();
            }
        }, 500);
    }

    handleFinishAndClose();
}
 
源代码9 项目: 365browser   文件: ChromeBrowserInitializer.java
private void preInflationStartup() {
    ThreadUtils.assertOnUiThread();
    if (mPreInflationStartupComplete) return;
    PathUtils.setPrivateDataDirectorySuffix(PRIVATE_DATA_DIRECTORY_SUFFIX);

    // Ensure critical files are available, so they aren't blocked on the file-system
    // behind long-running accesses in next phase.
    // Don't do any large file access here!
    ContentApplication.initCommandLine(mApplication);
    waitForDebuggerIfNeeded();
    ChromeStrictMode.configureStrictMode();
    ChromeWebApkHost.init();

    warmUpSharedPrefs();

    DeviceUtils.addDeviceSpecificUserAgentSwitch(mApplication);
    ApplicationStatus.registerStateListenerForAllActivities(
            createActivityStateListener());

    mPreInflationStartupComplete = true;
}
 
源代码10 项目: AndroidChromium   文件: ChromeBrowserProvider.java
@SuppressLint("NewApi")
private void notifyChange(final Uri uri) {
    // If the calling user is different than current one, we need to post a
    // task to notify change, otherwise, a system level hidden permission
    // INTERACT_ACROSS_USERS_FULL is needed.
    // The related APIs were added in API 17, it should be safe to fallback to
    // normal way for notifying change, because caller can't be other users in
    // devices whose API level is less than API 17.
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
        UserHandle callingUserHandle = Binder.getCallingUserHandle();
        if (callingUserHandle != null
                && !callingUserHandle.equals(android.os.Process.myUserHandle())) {
            ThreadUtils.postOnUiThread(new Runnable() {
                @Override
                public void run() {
                    getContext().getContentResolver().notifyChange(uri, null);
                }
            });
            return;
        }
    }
    getContext().getContentResolver().notifyChange(uri, null);
}
 
源代码11 项目: delion   文件: FeatureUtilities.java
/**
 * Determines whether or not the {@link RecognizerIntent#ACTION_WEB_SEARCH} {@link Intent}
 * is handled by any {@link android.app.Activity}s in the system.  The result will be cached for
 * future calls.  Passing {@code false} to {@code useCachedValue} will force it to re-query any
 * {@link android.app.Activity}s that can process the {@link Intent}.
 * @param context        The {@link Context} to use to check to see if the {@link Intent} will
 *                       be handled.
 * @param useCachedValue Whether or not to use the cached value from a previous result.
 * @return {@code true} if recognition is supported.  {@code false} otherwise.
 */
public static boolean isRecognitionIntentPresent(Context context, boolean useCachedValue) {
    ThreadUtils.assertOnUiThread();
    if (sHasRecognitionIntentHandler == null || !useCachedValue) {
        PackageManager pm = context.getPackageManager();
        List<ResolveInfo> activities = pm.queryIntentActivities(
                new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH), 0);
        sHasRecognitionIntentHandler = activities.size() > 0;
    }

    return sHasRecognitionIntentHandler;
}
 
public static DataReductionProxySettings getInstance() {
    ThreadUtils.assertOnUiThread();
    if (sSettings == null) {
        sSettings = new DataReductionProxySettings();
    }
    return sSettings;
}
 
源代码13 项目: AndroidChromium   文件: ConnectivityTask.java
private void postCallbackResult() {
    if (mCallback == null) return;
    ThreadUtils.postOnUiThread(new Runnable() {
        @Override
        public void run() {
            mCallback.onResult(get());
        }
    });
}
 
源代码14 项目: 365browser   文件: CustomTabsConnection.java
private boolean requestPostMessageChannelInternal(final CustomTabsSessionToken session,
        final Uri postMessageOrigin) {
    if (!mWarmupHasBeenCalled.get()) return false;
    if (!isCallerForegroundOrSelf() && !CustomTabActivity.isActiveSession(session)) {
        return false;
    }
    if (!mClientManager.bindToPostMessageServiceForSession(session)) return false;

    final int uid = Binder.getCallingUid();
    ThreadUtils.postOnUiThread(new Runnable() {
        @Override
        public void run() {
            // If the API is not enabled, we don't set the post message origin, which will
            // avoid PostMessageHandler initialization and disallow postMessage calls.
            if (!ChromeFeatureList.isEnabled(ChromeFeatureList.CCT_POST_MESSAGE_API)) return;

            // Attempt to verify origin synchronously. If successful directly initialize
            // postMessage channel for session.
            Uri verifiedOrigin = verifyOriginForSession(session, uid, postMessageOrigin);
            if (verifiedOrigin == null) {
                mClientManager.verifyAndInitializeWithPostMessageOriginForSession(
                        session, postMessageOrigin);
            } else {
                mClientManager.initializeWithPostMessageOriginForSession(
                        session, verifiedOrigin);
            }
        }
    });
    return true;
}
 
源代码15 项目: 365browser   文件: TemplateUrlService.java
/**
 * Called from native when template URL service is done loading.
 */
@CalledByNative
private void templateUrlServiceLoaded() {
    ThreadUtils.assertOnUiThread();
    for (LoadListener listener : mLoadListeners) {
        listener.onTemplateUrlServiceLoaded();
    }
}
 
/**
 * Create a new asynchronous request to select a client certificate.
 *
 * @param nativePtr         The native object responsible for this request.
 * @param window            A WindowAndroid instance.
 * @param keyTypes          The list of supported key exchange types.
 * @param encodedPrincipals The list of CA DistinguishedNames.
 * @param hostName          The server host name is available (empty otherwise).
 * @param port              The server port if available (0 otherwise).
 * @return                  true on success.
 * Note that nativeOnSystemRequestComplete will be called iff this method returns true.
 */
@CalledByNative
private static boolean selectClientCertificate(final long nativePtr, final WindowAndroid window,
        final String[] keyTypes, byte[][] encodedPrincipals, final String hostName,
        final int port) {
    ThreadUtils.assertOnUiThread();

    final Activity activity = window.getActivity().get();
    if (activity == null) {
        Log.w(TAG, "Certificate request on GC'd activity.");
        return false;
    }

    // Build the list of principals from encoded versions.
    Principal[] principals = null;
    if (encodedPrincipals.length > 0) {
        principals = new X500Principal[encodedPrincipals.length];
        try {
            for (int n = 0; n < encodedPrincipals.length; n++) {
                principals[n] = new X500Principal(encodedPrincipals[n]);
            }
        } catch (Exception e) {
            Log.w(TAG, "Exception while decoding issuers list: " + e);
            return false;
        }
    }

    KeyChainCertSelectionCallback callback =
            new KeyChainCertSelectionCallback(activity.getApplicationContext(),
                nativePtr);
    KeyChainCertSelectionWrapper keyChain = new KeyChainCertSelectionWrapper(activity,
            callback, keyTypes, principals, hostName, port, null);
    maybeShowCertSelection(keyChain, callback,
            new CertSelectionFailureDialog(activity));

    // We've taken ownership of the native ssl request object.
    return true;
}
 
源代码17 项目: delion   文件: DataReductionProxySettings.java
/**
 * Returns a singleton instance of the settings object.
 *
 * Needs the native library to be loaded, otherwise it will crash.
 */
public static DataReductionProxySettings getInstance() {
    ThreadUtils.assertOnUiThread();
    if (sSettings == null) {
        sSettings = new DataReductionProxySettings();
    }
    return sSettings;
}
 
源代码18 项目: AndroidChromium   文件: ChromeBrowserInitializer.java
public static void initNetworkChangeNotifier(Context context) {
    ThreadUtils.assertOnUiThread();
    TraceEvent.begin("NetworkChangeNotifier.init");
    // Enable auto-detection of network connectivity state changes.
    NetworkChangeNotifier.init(context);
    NetworkChangeNotifier.setAutoDetectConnectivityState(true);
    TraceEvent.end("NetworkChangeNotifier.init");
}
 
源代码19 项目: delion   文件: PartnerBrowserCustomizations.java
/**
 * Sets a callback that will be executed when the initialization is done.
 *
 * @param callback  This is called when the initialization is done.
 * @param timeoutMs If initializing takes more than this time since this function is called,
 *                  force run |callback| early. The unit is ms.
 */
public static void setOnInitializeAsyncFinished(final Runnable callback, long timeoutMs) {
    sInitializeAsyncCallbacks.add(callback);

    ThreadUtils.postOnUiThreadDelayed(
            new Runnable() {
                @Override
                public void run() {
                    if (sInitializeAsyncCallbacks.remove(callback)) callback.run();
                }
            },
            sIsInitialized ? 0 : timeoutMs);
}
 
源代码20 项目: 365browser   文件: PrintingContext.java
@CalledByNative
public void showPrintDialog() {
    ThreadUtils.assertOnUiThread();
    if (mController != null) {  // The native side doesn't check if printing is enabled
        mController.startPendingPrint(this);
    } else {
        Log.d(TAG, "Unable to start printing, feature not available.");
        // Printing disabled. Notify the native side to stop waiting.
        showSystemDialogDone();
    }
}
 
private static InputStream getInputStream(final AwContentsClient contentClient)
        throws IOException {
    final PipedInputStream inputStream = new PipedInputStream();
    final PipedOutputStream outputStream = new PipedOutputStream(inputStream);

    // Send the request to UI thread to callback to the client, and if it provides a
    // valid bitmap bounce on to the worker thread pool to compress it into the piped
    // input/output stream.
    ThreadUtils.runOnUiThread(new Runnable() {
        @Override
        public void run() {
            final Bitmap defaultVideoPoster = contentClient.getDefaultVideoPoster();
            if (defaultVideoPoster == null) {
                closeOutputStream(outputStream);
                return;
            }
            AsyncTask.THREAD_POOL_EXECUTOR.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        defaultVideoPoster.compress(Bitmap.CompressFormat.PNG, 100,
                                outputStream);
                        outputStream.flush();
                    } catch (IOException e) {
                        Log.e(TAG, null, e);
                    } finally {
                        closeOutputStream(outputStream);
                    }
                }
            });
        }
    });
    return inputStream;
}
 
源代码22 项目: AndroidChromium   文件: CustomTabsConnection.java
/**
 * High confidence mayLaunchUrl() call, that is:
 * - Tries to prerender if possible.
 * - An empty URL cancels the current prerender if any.
 * - If prerendering is not possible, makes sure that there is a spare renderer.
 */
private void highConfidenceMayLaunchUrl(CustomTabsSessionToken session,
        int uid, String url, Bundle extras, List<Bundle> otherLikelyBundles) {
    ThreadUtils.assertOnUiThread();
    if (TextUtils.isEmpty(url)) {
        cancelPrerender(session);
        return;
    }

    WarmupManager warmupManager = WarmupManager.getInstance();
    Profile profile = Profile.getLastUsedProfile();

    url = DataReductionProxySettings.getInstance().maybeRewriteWebliteUrl(url);
    int debugOverrideValue = NO_OVERRIDE;
    if (extras != null) debugOverrideValue = extras.getInt(DEBUG_OVERRIDE_KEY, NO_OVERRIDE);

    boolean didStartPrerender = false, didStartPrefetch = false;
    boolean mayPrerender = mayPrerender(session);
    if (mayPrerender) {
        if (debugOverrideValue == PREFETCH_ONLY) {
            didStartPrefetch = new ResourcePrefetchPredictor(profile).startPrefetching(url);
            if (didStartPrefetch) mSpeculation = SpeculationParams.forPrefetch(session, url);
        } else if (debugOverrideValue != NO_PRERENDERING) {
            didStartPrerender = prerenderUrl(session, url, extras, uid);
        }
    }
    preconnectUrls(otherLikelyBundles);
    if (!didStartPrefetch) warmupManager.maybePreconnectUrlAndSubResources(profile, url);
    if (!didStartPrerender) warmupManager.createSpareWebContents();
}
 
源代码23 项目: android-chromium   文件: ChildProcessLauncher.java
/**
 * Unbind a high priority process which was previous bound with bindAsHighPriority.
 * @param pid The process handle of the service.
 */
void unbindAsHighPriority(final int pid) {
    final ChildProcessConnection connection = sServiceMap.get(pid);
    if (connection == null) {
        LogPidWarning(pid, "Tried to unbind non-existent connection");
        return;
    }
    if (!connection.isStrongBindingBound()) return;

    // This runnable performs the actual unbinding. It will be executed synchronously when
    // on low-end devices and posted with a delay otherwise.
    Runnable doUnbind = new Runnable() {
        @Override
        public void run() {
            synchronized (mCountLock) {
                if (connection.isStrongBindingBound()) {
                    decrementOomCount(pid);
                    connection.detachAsActive();
                }
            }
        }
    };

    if (SysUtils.isLowEndDevice()) {
        doUnbind.run();
    } else {
        ThreadUtils.postOnUiThreadDelayed(doUnbind, DETACH_AS_ACTIVE_HIGH_END_DELAY_MILLIS);
    }
}
 
源代码24 项目: 365browser   文件: AccountTrackerService.java
/**
* Register an |observer| to observe system accounts seeding status.
*/
public void addSystemAccountsSeededListener(OnSystemAccountsSeededListener observer) {
    ThreadUtils.assertOnUiThread();
    mSystemAccountsSeedingObservers.addObserver(observer);
    if (mSystemAccountsSeedingStatus == SystemAccountsSeedingStatus.SEEDING_DONE) {
        observer.onSystemAccountsSeedingComplete();
    }
}
 
源代码25 项目: android-chromium   文件: SyncController.java
/**
 * Retrieve the singleton instance of this class.
 *
 * @param context the current context.
 * @return the singleton instance.
 */
public static SyncController get(Context context) {
    ThreadUtils.assertOnUiThread();
    if (sInstance == null) {
        sInstance = new SyncController(context.getApplicationContext());
    }
    return sInstance;
}
 
源代码26 项目: android-chromium   文件: PersonalDataManager.java
public List<CreditCard> getCreditCards() {
    ThreadUtils.assertOnUiThread();
    int count = nativeGetCreditCardCount(mPersonalDataManagerAndroid);
    List<CreditCard> cards = new ArrayList<CreditCard>(count);
    for (int i = 0; i < count; i++) {
        cards.add(nativeGetCreditCardByIndex(mPersonalDataManagerAndroid, i));
    }
    return cards;
}
 
源代码27 项目: android-chromium   文件: LocationProvider.java
/**
 * Start listening for location updates until we're told to quit. May be
 * called in any thread.
 * @param gpsEnabled Whether or not we're interested in high accuracy GPS.
 */
@CalledByNative
public boolean start(final boolean gpsEnabled) {
    FutureTask<Void> task = new FutureTask<Void>(new Runnable() {
        @Override
        public void run() {
            mImpl.start(gpsEnabled);
        }
    }, null);
    ThreadUtils.runOnUiThread(task);
    return true;
}
 
源代码28 项目: AndroidChromium   文件: PrecacheLauncher.java
/**
 * If precaching is enabled, then allow the PrecacheController to be launched and signal Chrome
 * when conditions are right to start precaching. If precaching is disabled, prevent the
 * PrecacheController from ever starting.
 *
 * @param context any context within the application
 */
@VisibleForTesting
void updateEnabled(final Context context) {
    Log.v(TAG, "updateEnabled starting");
    ThreadUtils.postOnUiThread(new Runnable() {
        @Override
        public void run() {
            mCalled = true;
            final ProfileSyncService sync = ProfileSyncService.get();

            if (mListener == null && sync != null) {
                mListener = new ProfileSyncService.SyncStateChangedListener() {
                    public void syncStateChanged() {
                        if (sync.isBackendInitialized()) {
                            mSyncInitialized = true;
                            updateEnabledSync(context);
                        }
                    }
                };
                sync.addSyncStateChangedListener(mListener);
            }

            if (mListener != null) {
                // Call the listener once, in case the sync backend is already initialized.
                mListener.syncStateChanged();
            }
            Log.v(TAG, "updateEnabled complete");
        }
    });
}
 
源代码29 项目: delion   文件: OAuth2TokenService.java
/**
 * Called by native to retrieve OAuth2 tokens.
 *
 * @param username The native username (full address).
 * @param scope The scope to get an auth token for (without Android-style 'oauth2:' prefix).
 * @param nativeCallback The pointer to the native callback that should be run upon completion.
 */
@CalledByNative
public static void getOAuth2AuthToken(
        Context context, String username, String scope, final long nativeCallback) {
    Account account = getAccountOrNullFromUsername(context, username);
    if (account == null) {
        ThreadUtils.postOnUiThread(new Runnable() {
            @Override
            public void run() {
                nativeOAuth2TokenFetched(null, false, nativeCallback);
            }
        });
        return;
    }
    String oauth2Scope = OAUTH2_SCOPE_PREFIX + scope;

    AccountManagerHelper accountManagerHelper = AccountManagerHelper.get(context);
    accountManagerHelper.getAuthToken(
            account, oauth2Scope, new AccountManagerHelper.GetAuthTokenCallback() {
                @Override
                public void tokenAvailable(String token) {
                    nativeOAuth2TokenFetched(token, false, nativeCallback);
                }

                @Override
                public void tokenUnavailable(boolean isTransientError) {
                    nativeOAuth2TokenFetched(null, isTransientError, nativeCallback);
                }
            });
}
 
源代码30 项目: AndroidChromium   文件: HelpAndFeedback.java
/**
 * Returns the singleton instance of HelpAndFeedback, creating it if needed.
 */
@SuppressFBWarnings("LI_LAZY_INIT_STATIC")
public static HelpAndFeedback getInstance(Context context) {
    ThreadUtils.assertOnUiThread();
    if (sInstance == null) {
        sInstance = ((ChromeApplication) context.getApplicationContext())
                .createHelpAndFeedback();
    }
    return sInstance;
}