public ChildProcessConnection allocate( Context context, ChildProcessConnection.DeathCallback deathCallback, ChromiumLinkerParams chromiumLinkerParams, boolean alwaysInForeground) { synchronized (mConnectionLock) { if (mFreeConnectionIndices.isEmpty()) { Log.d(TAG, "Ran out of services to allocate."); return null; } int slot = mFreeConnectionIndices.remove(0); assert mChildProcessConnections[slot] == null; mChildProcessConnections[slot] = new ChildProcessConnectionImpl( context, slot, mInSandbox, deathCallback, mChildClass, chromiumLinkerParams, alwaysInForeground); Log.d(TAG, "Allocator allocated a connection, sandbox: " + mInSandbox + ", slot: " + slot); return mChildProcessConnections[slot]; } }
@Override public Bundle getAuthToken( AccountAuthenticatorResponse response, Account account, String authTokenType, Bundle options) throws NetworkErrorException { Log.d(TAG, "getAuthToken(%s)", account.name); Bundle result = new Bundle(); if (AccountData.get(account.name, mContext).isAuthenticated()) { Log.d(TAG, "getAuthToken(): Returning dummy SPNEGO auth token"); result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name); result.putString(AccountManager.KEY_ACCOUNT_TYPE, account.type); result.putString(AccountManager.KEY_AUTHTOKEN, Constants.AUTH_TOKEN); result.putInt(HttpNegotiateConstants.KEY_SPNEGO_RESULT, 0); } else { Log.d(TAG, "getAuthToken(): Asking for credentials confirmation"); Intent intent = SpnegoAuthenticatorActivity.getConfirmCredentialsIntent(mContext, account.name, response); result.putParcelable(AccountManager.KEY_INTENT, intent); // We need to show a notification in case the caller can't use the intent directly. showConfirmCredentialsNotification(mContext, intent); } return result; }
private static void startInternal( Context context, final String[] commandLine, int childProcessId, FileDescriptorInfo[] filesToBeMapped, long clientContext, int callbackType, boolean inSandbox) { try { TraceEvent.begin("ChildProcessLauncher.startInternal"); ChildProcessConnection allocatedConnection = null; synchronized (ChildProcessLauncher.class) { if (inSandbox) { allocatedConnection = sSpareSandboxedConnection; sSpareSandboxedConnection = null; } } if (allocatedConnection == null) { boolean alwaysInForeground = false; if (callbackType == CALLBACK_FOR_GPU_PROCESS) alwaysInForeground = true; allocatedConnection = allocateBoundConnection(context, commandLine, inSandbox, alwaysInForeground); if (allocatedConnection == null) { Log.d(TAG, "Allocation of new service failed. Queuing up pending spawn."); sPendingSpawnQueue.enqueue( new PendingSpawnData( context, commandLine, childProcessId, filesToBeMapped, clientContext, callbackType, inSandbox)); return; } } Log.d( TAG, "Setting up connection to process: slot=" + allocatedConnection.getServiceNumber()); triggerConnectionSetup( allocatedConnection, commandLine, childProcessId, filesToBeMapped, callbackType, clientContext); } finally { TraceEvent.end("ChildProcessLauncher.startInternal"); } }
@CalledByNative public void startCapture() { Log.d(TAG, "startCapture"); synchronized (mCaptureStateLock) { if (mCaptureState != CaptureState.ALLOWED) { Log.e(TAG, "startCapture() invoked without user permission."); return; } } mMediaProjection = mMediaProjectionManager.getMediaProjection(mResultCode, mResultData); if (mMediaProjection == null) { Log.e(TAG, "mMediaProjection is null"); return; } mMediaProjection.registerCallback(new MediaProjectionCallback(), null); mThread = new HandlerThread("ScreenCapture"); mThread.start(); mBackgroundHandler = new Handler(mThread.getLooper()); // On Android M and above, YUV420 is prefered. Some Android L devices will silently // fail with YUV420, so keep with RGBA_8888 on L. if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { mFormat = PixelFormat.RGBA_8888; } else { mFormat = ImageFormat.YUV_420_888; } maybeDoRotation(); createImageReaderWithFormat(); createVirtualDisplay(); changeCaptureStateAndNotify(CaptureState.STARTED); }
@CalledByNative private void focusedNodeChanged(boolean isEditable) { Log.d(TAG, "focusedNodeChanged: isEditable [%b]", isEditable); if (mTextInputType != TextInputType.NONE && mInputConnection != null && isEditable) { restartInput(); } }
// This method was deprecated in API level 23 by onAttach(Context). // TODO(braveyao): remove this method after the minSdkVersion of chrome is 23, // https://crbug.com/614172. @SuppressWarnings("deprecation") @Override public void onAttach(Activity activity) { super.onAttach(activity); Log.d(TAG, "onAttach"); changeCaptureStateAndNotify(CaptureState.ATTACHED); }
@Override public Bundle updateCredentials( AccountAuthenticatorResponse response, Account account, String authTokenType, Bundle options) throws NetworkErrorException { Log.d(TAG, "updateCredentials(%s)", account.name); return unsupportedOperationBundle("updateCredentials"); }
@Override public Bundle confirmCredentials( AccountAuthenticatorResponse response, Account account, Bundle options) throws NetworkErrorException { Log.d(TAG, "confirmCredentials(%s)", account.name); return unsupportedOperationBundle("confirmCredentials"); }
/** Move cursor to the end of the current selection. */ public void moveCursorToSelectionEnd() { Log.d(TAG, "movecursorToEnd"); if (mInputConnection != null) { int selectionEnd = Selection.getSelectionEnd(mEditable); mInputConnection.setSelection(selectionEnd, selectionEnd); } }
public boolean dispatchKeyEvent(KeyEvent event) { Log.d( TAG, "dispatchKeyEvent: action [%d], keycode [%d]", event.getAction(), event.getKeyCode()); if (mInputConnection != null) { return mInputConnection.sendKeyEvent(event); } return sendKeyEvent(event); }
/** * Always process the violation on the UI thread. This ensures other crash reports are not * corrupted. Since each individual user has a very small chance of uploading each violation, and * we have a hard cap of 3 per session, this will not affect performance too much. * * @param violationInfo The violation info from the StrictMode violation in question. */ @UiThread private static void reportStrictModeViolation(Object violationInfo) { try { Field crashInfoField = violationInfo.getClass().getField("crashInfo"); ApplicationErrorReport.CrashInfo crashInfo = (ApplicationErrorReport.CrashInfo) crashInfoField.get(violationInfo); String stackTrace = crashInfo.stackTrace; if (stackTrace == null) { Log.d(TAG, "StrictMode violation stack trace was null."); } else { Log.d(TAG, "Upload stack trace: " + stackTrace); JavaExceptionReporter.reportStackTrace(stackTrace); } } catch (Exception e) { // Ignore all exceptions. Log.d(TAG, "Could not handle observed StrictMode violation.", e); } }
/** Show soft keyboard only if it is the current keyboard configuration. */ private void showSoftKeyboard() { Log.d(TAG, "showSoftKeyboard"); mInputMethodManagerWrapper.showSoftInput( mViewEmbedder.getAttachedView(), 0, mViewEmbedder.getNewShowKeyboardReceiver()); if (mViewEmbedder.getAttachedView().getResources().getConfiguration().keyboard != Configuration.KEYBOARD_NOKEYS) { mViewEmbedder.onKeyboardBoundsUnchanged(); } }
/** Call this when keyboard configuration has changed. */ public void onKeyboardConfigurationChanged() { Log.d(TAG, "onKeyboardConfigurationChanged: mTextInputType [%d]", mTextInputType); if (mTextInputType != TextInputType.NONE) { restartInput(); // By default, we show soft keyboard on keyboard changes. This is useful // when the user switches from hardware keyboard to software keyboard. // TODO(changwan): check if we can skip this for hardware keyboard configurations. showSoftKeyboard(); } }
/** * Fires an Intent to open a downloaded item. * * @param context Context to use. * @param intent Intent that can be fired. * @return Whether an Activity was successfully started for the Intent. */ static boolean fireOpenIntentForDownload(Context context, Intent intent) { try { if (TextUtils.equals(intent.getPackage(), context.getPackageName())) { IntentHandler.startActivityForTrustedIntent(intent, context); } else { context.startActivity(intent); } return true; } catch (ActivityNotFoundException ex) { Log.d( TAG, "Activity not found for " + intent.getType() + " over " + intent.getData().getScheme(), ex); } catch (SecurityException ex) { Log.d(TAG, "cannot open intent: " + intent, ex); } return false; }
@Override public void onMessageReceived(CastDevice castDevice, String namespace, String message) { Log.d( TAG, "Received message from Cast device: namespace=\"" + namespace + "\" message=\"" + message + "\""); mSession.getMessageHandler().onMessageReceived(namespace, message); }
/** * Terminates a child process. This may be called from any thread. * * @param pid The pid (process handle) of the service connection obtained from {@link #start}. */ @CalledByNative static void stop(int pid) { Log.d(TAG, "stopping child connection: pid=" + pid); ChildProcessConnection connection = sServiceMap.remove(pid); if (connection == null) { logPidWarning(pid, "Tried to stop non-existent connection"); return; } sBindingManager.clearConnection(pid); connection.stop(); freeConnection(connection); }
/** Hide soft keyboard. */ private void hideKeyboard() { Log.d(TAG, "hideKeyboard"); View view = mViewEmbedder.getAttachedView(); if (mInputMethodManagerWrapper.isActive(view)) { // NOTE: we should not set ResultReceiver here. Otherwise, IMM will own ContentViewCore // and ImeAdapter even after input method goes away and result gets received. mInputMethodManagerWrapper.hideSoftInputFromWindow(view.getWindowToken(), 0, null); } // Detach input connection by returning null from onCreateInputConnection(). if (mTextInputType == TextInputType.NONE && mInputConnection != null) { restartInput(); } }
/** * 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); } }
/** @see View#onCreateInputConnection(EditorInfo) */ public AdapterInputConnection onCreateInputConnection(EditorInfo outAttrs) { // Without this line, some third-party IMEs will try to compose text even when // not on an editable node. Even when we return null here, key events can still go through // ImeAdapter#dispatchKeyEvent(). if (mTextInputType == TextInputType.NONE) { mInputConnection = null; Log.d(TAG, "onCreateInputConnection returns null."); return null; } if (!isTextInputType(mTextInputType)) { // Although onCheckIsTextEditor will return false in this case, the EditorInfo // is still used by the InputMethodService. Need to make sure the IME doesn't // enter fullscreen mode. outAttrs.imeOptions = EditorInfo.IME_FLAG_NO_FULLSCREEN; } int initialSelStart = Selection.getSelectionStart(mEditable); int initialSelEnd = outAttrs.initialSelEnd = Selection.getSelectionEnd(mEditable); mInputConnection = mInputConnectionFactory.get( mViewEmbedder.getAttachedView(), this, initialSelStart, initialSelEnd, outAttrs); Log.d(TAG, "onCreateInputConnection"); return mInputConnection; }
@Override public Bundle hasFeatures( AccountAuthenticatorResponse response, Account account, String[] features) throws NetworkErrorException { Log.d(TAG, "hasFeatures(%s)", Arrays.asList(features)); Bundle result = new Bundle(); // All our accounts only have the SPNEGO feature, other features are not supported. for (String feature : features) { if (!feature.equals(HttpNegotiateConstants.SPNEGO_FEATURE)) { result.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, false); return result; } } result.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, true); return result; }
@Override public Bundle addAccount( AccountAuthenticatorResponse response, String accountType, String authTokenType, String[] requiredFeatures, Bundle options) throws NetworkErrorException { Log.d(TAG, "addAccount()"); // Delegate to the activity to get the account information from the user. Bundle bundle = new Bundle(); bundle.putParcelable( AccountManager.KEY_INTENT, SpnegoAuthenticatorActivity.getAddAccountIntent(mContext, response)); return bundle; }
@CalledByNative public void stopCapture() { Log.d(TAG, "stopCapture"); synchronized (mCaptureStateLock) { if (mMediaProjection != null && mCaptureState == CaptureState.STARTED) { mMediaProjection.stop(); changeCaptureStateAndNotify(CaptureState.STOPPING); } while (mCaptureState != CaptureState.STOPPED) { try { mCaptureStateLock.wait(); } catch (InterruptedException ex) { Log.e(TAG, "ScreenCaptureEvent: " + ex); } } } }
@CalledByNative private void populateUnderlinesFromSpans(CharSequence text, long underlines) { Log.d(TAG, "populateUnderlinesFromSpans: text [%s], underlines [%d]", text, underlines); if (!(text instanceof SpannableString)) return; SpannableString spannableString = ((SpannableString) text); CharacterStyle spans[] = spannableString.getSpans(0, text.length(), CharacterStyle.class); for (CharacterStyle span : spans) { if (span instanceof BackgroundColorSpan) { nativeAppendBackgroundColorSpan( underlines, spannableString.getSpanStart(span), spannableString.getSpanEnd(span), ((BackgroundColorSpan) span).getBackgroundColor()); } else if (span instanceof UnderlineSpan) { nativeAppendUnderlineSpan( underlines, spannableString.getSpanStart(span), spannableString.getSpanEnd(span)); } } }
public void free(ChildProcessConnection connection) { synchronized (mConnectionLock) { int slot = connection.getServiceNumber(); if (mChildProcessConnections[slot] != connection) { int occupier = mChildProcessConnections[slot] == null ? -1 : mChildProcessConnections[slot].getServiceNumber(); Log.e( TAG, "Unable to find connection to free in slot: " + slot + " already occupied by service: " + occupier); assert false; } else { mChildProcessConnections[slot] = null; assert !mFreeConnectionIndices.contains(slot); mFreeConnectionIndices.add(slot); Log.d(TAG, "Allocator freed a connection, sandbox: " + mInSandbox + ", slot: " + slot); } } }
@CalledByNative public boolean startPrompt() { Log.d(TAG, "startPrompt"); Activity activity = ApplicationStatus.getLastTrackedFocusedActivity(); if (activity == null) { Log.e(TAG, "activity is null"); return false; } FragmentManager fragmentManager = activity.getFragmentManager(); FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); fragmentTransaction.add(this, "screencapture"); try { fragmentTransaction.commit(); } catch (RuntimeException e) { Log.e(TAG, "ScreenCaptureExcaption " + e); return false; } synchronized (mCaptureStateLock) { while (mCaptureState != CaptureState.ATTACHED) { try { mCaptureStateLock.wait(); } catch (InterruptedException ex) { Log.e(TAG, "ScreenCaptureException: " + ex); } } } try { startActivityForResult( mMediaProjectionManager.createScreenCaptureIntent(), REQUEST_MEDIA_PROJECTION); } catch (android.content.ActivityNotFoundException e) { Log.e(TAG, "ScreenCaptureException " + e); return false; } return true; }
@Override public boolean sendStringCastMessage( final String message, final String namespace, final String clientId, final int sequenceNumber) { if (isApiClientInvalid()) return false; Log.d(TAG, "Sending message to Cast device in namespace %s: %s", namespace, message); try { Cast.CastApi.sendMessage(mApiClient, namespace, message) .setResultCallback( new ResultCallback<Status>() { @Override public void onResult(Status result) { if (!result.isSuccess()) { // TODO(avayvod): should actually report back to the page. // See https://crbug.com/550445. Log.e(TAG, "Failed to send the message: " + result); return; } // Media commands wait for the media status update as a result. if (CastMessageHandler.MEDIA_NAMESPACE.equals(namespace)) return; // App messages wait for the empty message with the sequence // number. mMessageHandler.onAppMessageSent(clientId, sequenceNumber); } }); } catch (Exception e) { Log.e(TAG, "Exception while sending message", e); return false; } return true; }
/** * Shows or hides the keyboard based on passed parameters. * * @param textInputType Text input type for the currently focused field in renderer. * @param textInputFlags Text input flags. * @param showIfNeeded Whether the keyboard should be shown if it is currently hidden. */ public void updateKeyboardVisibility( int textInputType, int textInputFlags, boolean showIfNeeded) { Log.d( TAG, "updateKeyboardVisibility: type [%d->%d], flags [%d], show [%b], ", mTextInputType, textInputType, textInputFlags, showIfNeeded); mTextInputFlags = textInputFlags; if (mTextInputType != textInputType) { mTextInputType = textInputType; // No need to restart if we are going to hide anyways. if (textInputType != TextInputType.NONE) restartInput(); } // There is no API for us to get notified of user's dismissal of keyboard. // Therefore, we should try to show keyboard even when text input type hasn't changed. if (textInputType != TextInputType.NONE) { if (showIfNeeded) showSoftKeyboard(); } else { hideKeyboard(); } }
@CalledByNative void detach() { Log.d(TAG, "detach"); mNativeImeAdapterAndroid = 0; }
@Override public Bundle editProperties(AccountAuthenticatorResponse response, String accountType) { Log.d(TAG, "editProperties(%s)", accountType); return unsupportedOperationBundle("editProperties"); }
@Override public String getAuthTokenLabel(String authTokenType) { Log.d(TAG, "getAuthTokenLabel(%s)", authTokenType); return "Spnego " + authTokenType; }