@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; }
/** * Restores the encryption key from the given Bundle. Expected to be called when an Activity is * being restored after being killed in the background. If the Activity was explicitly killed by * the user, Android gives no Bundle (and therefore no key). * * @param savedInstanceState Bundle containing the Activity's previous state. Null if the user * explicitly killed the Activity. * @return True if the data was restored successfully from the Bundle, or if the CipherData in use * matches the Bundle contents. */ public boolean restoreFromBundle(Bundle savedInstanceState) { if (savedInstanceState == null) return false; byte[] wrappedKey = savedInstanceState.getByteArray(BUNDLE_KEY); byte[] iv = savedInstanceState.getByteArray(BUNDLE_IV); if (wrappedKey == null || iv == null) return false; try { Key bundledKey = new SecretKeySpec(wrappedKey, "AES"); synchronized (mDataLock) { if (mData == null) { mData = new CipherData(bundledKey, iv); return true; } else if (mData.key.equals(bundledKey) && Arrays.equals(mData.iv, iv)) { return true; } else { Log.e(TAG, "Attempted to restore different cipher data."); } } } catch (IllegalArgumentException e) { Log.e(TAG, "Error in restoring the key from the bundle."); } return false; }
private void waitForDebuggerIfNeeded() { if (CommandLine.getInstance().hasSwitch(BaseSwitches.WAIT_FOR_JAVA_DEBUGGER)) { Log.e(TAG, "Waiting for Java debugger to connect..."); android.os.Debug.waitForDebugger(); Log.e(TAG, "Java debugger connected. Resuming execution."); } }
@Override protected boolean isStartedUpCorrectly(Intent intent) { int tabId = ActivityDelegate.getTabIdFromIntent(getIntent()); // Fire a MAIN Intent to send the user back through ChromeLauncherActivity. Log.e(TAG, "User shouldn't be here. Sending back to ChromeLauncherActivity."); // Try to bring this tab forward after migration. Intent tabbedIntent = null; if (tabId != Tab.INVALID_TAB_ID) tabbedIntent = Tab.createBringTabToFrontIntent(tabId); if (tabbedIntent == null) { tabbedIntent = new Intent(Intent.ACTION_MAIN); tabbedIntent.setPackage(getPackageName()); } // Launch the other Activity in its own task so it stays when this one finishes. tabbedIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); tabbedIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT); startActivity(tabbedIntent); overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out); Log.e(TAG, "Discarding Intent: Tab = " + tabId); return false; }
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); } }
@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); }
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]; } }
/** * Called from native code to share a surface texture with another child process. Through using * the callback object the browser is used as a proxy to route the call to the correct process. * * @param pid Process handle of the child process to share the SurfaceTexture with. * @param surfaceObject The Surface or SurfaceTexture to share with the other child process. * @param primaryID Used to route the call to the correct client instance. * @param secondaryID Used to route the call to the correct client instance. */ @SuppressWarnings("unused") @CalledByNative private void establishSurfaceTexturePeer( int pid, Object surfaceObject, int primaryID, int secondaryID) { if (mCallback == null) { Log.e(TAG, "No callback interface has been provided."); return; } Surface surface = null; boolean needRelease = false; if (surfaceObject instanceof Surface) { surface = (Surface) surfaceObject; } else if (surfaceObject instanceof SurfaceTexture) { surface = new Surface((SurfaceTexture) surfaceObject); needRelease = true; } else { Log.e(TAG, "Not a valid surfaceObject: %s", surfaceObject); return; } try { mCallback.establishSurfacePeer(pid, surface, primaryID, secondaryID); } catch (RemoteException e) { Log.e(TAG, "Unable to call establishSurfaceTexturePeer: %s", e); return; } finally { if (needRelease) { surface.release(); } } }
/** Registers this object with the location service. */ private void registerForLocationUpdates(boolean enableHighAccuracy) { ensureLocationManagerCreated(); if (usePassiveOneShotLocation()) return; assert !mIsRunning; mIsRunning = true; // We're running on the main thread. The C++ side is responsible to // bounce notifications to the Geolocation thread as they arrive in the mainLooper. try { Criteria criteria = new Criteria(); if (enableHighAccuracy) criteria.setAccuracy(Criteria.ACCURACY_FINE); mLocationManager.requestLocationUpdates( 0, 0, criteria, this, ThreadUtils.getUiThreadLooper()); } catch (SecurityException e) { Log.e( TAG, "Caught security exception while registering for location updates " + "from the system. The application does not have sufficient geolocation " + "permissions."); unregisterFromLocationUpdates(); // Propagate an error to JavaScript, this can happen in case of WebView // when the embedding app does not have sufficient permissions. LocationProviderAdapter.newErrorAvailable( "application does not have sufficient " + "geolocation permissions."); } catch (IllegalArgumentException e) { Log.e(TAG, "Caught IllegalArgumentException registering for location updates."); unregisterFromLocationUpdates(); assert false; } }
/** * Return the OpenSSLEngine object corresponding to a given PrivateKey object. * * <p>This shall only be used for Android 4.1 to work around a platform bug. See * https://crbug.com/381465. * * @param privateKey The PrivateKey handle. * @return The OpenSSLEngine object (or null if not available) */ @CalledByNative private static Object getOpenSSLEngineForPrivateKey(PrivateKey privateKey) { // Find the system OpenSSLEngine class. Class<?> engineClass; try { engineClass = Class.forName("org.apache.harmony.xnet.provider.jsse.OpenSSLEngine"); } catch (Exception e) { // This may happen if the target device has a completely different // implementation of the java.security APIs, compared to vanilla // Android. Highly unlikely, but still possible. Log.e(TAG, "Cannot find system OpenSSLEngine class: " + e); return null; } Object opensslKey = getOpenSSLKeyForPrivateKey(privateKey); if (opensslKey == null) return null; try { // Use reflection to invoke the 'getEngine' method on the // result of the getOpenSSLKey(). Method getEngine; try { getEngine = opensslKey.getClass().getDeclaredMethod("getEngine"); } catch (Exception e) { // Bail here too, something really not working as expected. Log.e(TAG, "No getEngine() method on OpenSSLKey member:" + e); return null; } getEngine.setAccessible(true); Object engine = null; try { engine = getEngine.invoke(opensslKey); } finally { getEngine.setAccessible(false); } if (engine == null) { // The PrivateKey is probably rotten for some reason. Log.e(TAG, "getEngine() returned null"); } // Sanity-check the returned engine. if (!engineClass.isInstance(engine)) { Log.e( TAG, "Engine is not an OpenSSLEngine instance, its class name is:" + engine.getClass().getCanonicalName()); return null; } return engine; } catch (Exception e) { Log.e(TAG, "Exception while trying to retrieve OpenSSLEngine object: " + e); return null; } }
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"); } }
@SuppressWarnings("unused") @CalledByNative private void destroySurfaceTextureSurface(int surfaceTextureId, int clientId) { if (mCallback == null) { Log.e(TAG, "No callback interface has been provided."); return; } try { mCallback.unregisterSurfaceTextureSurface(surfaceTextureId, clientId); } catch (RemoteException e) { Log.e(TAG, "Unable to call unregisterSurfaceTextureSurface: %s", e); } }
@SuppressWarnings("unused") @CalledByNative private Surface getSurfaceTextureSurface(int surfaceTextureId) { if (mCallback == null) { Log.e(TAG, "No callback interface has been provided."); return null; } try { return mCallback.getSurfaceTextureSurface(surfaceTextureId).getSurface(); } catch (RemoteException e) { Log.e(TAG, "Unable to call getSurfaceTextureSurface: %s", e); return null; } }
// 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); }
/** @see BaseInputConnection#setComposingRegion(int, int) */ @Override public boolean setComposingRegion(int start, int end) { if (DEBUG) Log.w(TAG, "setComposingRegion [" + start + " " + end + "]"); int textLength = mEditable.length(); int a = Math.min(start, end); int b = Math.max(start, end); if (a < 0) a = 0; if (b < 0) b = 0; if (a > textLength) a = textLength; if (b > textLength) b = textLength; CharSequence regionText = null; if (a == b) { removeComposingSpans(mEditable); } else { if (a == 0 && b == mEditable.length()) { regionText = mEditable.subSequence(a, b); // If setting composing region that matches, at least in length, of the entire // editable region then check it for image placeholders. If any are found, // don't continue this operation. // This fixes the problem where, on Android 4.3, pasting an image is followed // by setting the composing region which then causes the image to be deleted. // http://crbug.com/466755 for (int i = a; i < b; ++i) { if (regionText.charAt(i) == '\uFFFC') return true; } } super.setComposingRegion(a, b); } updateSelectionIfRequired(); return mImeAdapter.setComposingRegion(regionText, a, b); }
@Override protected void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); String[] parameters = getIntent().getStringArrayExtra(EXTRAS); if (parameters != null) { for (String s : parameters) { s = s.replace("\\,", ","); } } if (Intent.ACTION_VIEW.equals(getIntent().getAction())) { Uri uri = getIntent().getData(); if (uri != null) { Log.i(TAG, "MojoShellActivity opening " + uri); if (parameters == null) { parameters = new String[] {uri.toString()}; } else { String[] newParameters = new String[parameters.length + 1]; System.arraycopy(parameters, 0, newParameters, 0, parameters.length); newParameters[parameters.length] = uri.toString(); parameters = newParameters; } } } // TODO(ppi): Gotcha - the call below will work only once per process lifetime, but the OS // has no obligation to kill the application process between destroying and restarting the // activity. If the application process is kept alive, initialization parameters sent with // the intent will be stale. // TODO(qsr): We should be passing application context here as required by // InitApplicationContext on the native side. Currently we can't, as PlatformViewportAndroid // relies on this being the activity context. ShellMain.ensureInitialized(this, parameters); ShellMain.start(); }
@Override @SuppressFBWarnings("DM_EXIT") public void onDestroy() { Log.i(TAG, "Destroying ChildProcessService pid=%d", Process.myPid()); super.onDestroy(); if (mActivitySemaphore.tryAcquire()) { // TODO(crbug.com/457406): This is a bit hacky, but there is no known better solution // as this service will get reused (at least if not sandboxed). // In fact, we might really want to always exit() from onDestroy(), not just from // the early return here. System.exit(0); return; } synchronized (mMainThread) { try { while (!mLibraryInitialized) { // Avoid a potential race in calling through to native code before the library // has loaded. mMainThread.wait(); } } catch (InterruptedException e) { // Ignore } } // Try to shutdown the MainThread gracefully, but it might not // have chance to exit normally. nativeShutdownMainThread(); }
private void ensureLocationManagerCreated() { if (mLocationManager != null) return; mLocationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE); if (mLocationManager == null) { Log.e(TAG, "Could not get location manager."); } }
// SET_VOLUME messages have a |level| and |muted| properties. One of them is // |null| and the other one isn't. |muted| is expected to be a boolean while // |level| is a float from 0.0 to 1.0. // Example: // { // "volume" { // "level": 0.9, // "muted": null // } // } @Override public HandleVolumeMessageResult handleVolumeMessage( JSONObject volume, final String clientId, final int sequenceNumber) throws JSONException { if (volume == null) return new HandleVolumeMessageResult(false, false); if (isApiClientInvalid()) return new HandleVolumeMessageResult(false, false); boolean waitForVolumeChange = false; try { if (!volume.isNull("muted")) { boolean newMuted = volume.getBoolean("muted"); if (Cast.CastApi.isMute(mApiClient) != newMuted) { Cast.CastApi.setMute(mApiClient, newMuted); waitForVolumeChange = true; } } if (!volume.isNull("level")) { double newLevel = volume.getDouble("level"); double currentLevel = Cast.CastApi.getVolume(mApiClient); if (!Double.isNaN(currentLevel) && Math.abs(currentLevel - newLevel) > MIN_VOLUME_LEVEL_DELTA) { Cast.CastApi.setVolume(mApiClient, newLevel); waitForVolumeChange = true; } } } catch (IOException e) { Log.e(TAG, "Failed to send volume command: " + e); return new HandleVolumeMessageResult(false, false); } return new HandleVolumeMessageResult(true, waitForVolumeChange); }
@Override public Bundle confirmCredentials( AccountAuthenticatorResponse response, Account account, Bundle options) throws NetworkErrorException { Log.d(TAG, "confirmCredentials(%s)", account.name); return unsupportedOperationBundle("confirmCredentials"); }
@Override public Bundle updateCredentials( AccountAuthenticatorResponse response, Account account, String authTokenType, Bundle options) throws NetworkErrorException { Log.d(TAG, "updateCredentials(%s)", account.name); return unsupportedOperationBundle("updateCredentials"); }
@CalledByNative private void focusedNodeChanged(boolean isEditable) { Log.d(TAG, "focusedNodeChanged: isEditable [%b]", isEditable); if (mTextInputType != TextInputType.NONE && mInputConnection != null && isEditable) { restartInput(); } }
/** 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); } }
/** @see BaseInputConnection#endBatchEdit() */ @Override public boolean endBatchEdit() { if (mNumNestedBatchEdits == 0) return false; --mNumNestedBatchEdits; if (DEBUG) Log.w(TAG, "endBatchEdit [" + (mNumNestedBatchEdits == 0) + "]"); if (mNumNestedBatchEdits == 0) updateSelectionIfRequired(); return mNumNestedBatchEdits != 0; }
@SuppressWarnings("unused") @CalledByNative private void createSurfaceTextureSurface( int surfaceTextureId, int clientId, SurfaceTexture surfaceTexture) { if (mCallback == null) { Log.e(TAG, "No callback interface has been provided."); return; } Surface surface = new Surface(surfaceTexture); try { mCallback.registerSurfaceTextureSurface(surfaceTextureId, clientId, surface); } catch (RemoteException e) { Log.e(TAG, "Unable to call registerSurfaceTextureSurface: %s", e); } surface.release(); }
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); }
@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); } } } }
/** * 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); } }
private static void deleteFileForOverwrite(DownloadInfo info) { assert !ThreadUtils.runningOnUiThread(); File dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS); if (!dir.isDirectory()) return; final File file = new File(dir, info.getFileName()); if (!file.delete()) { Log.e(TAG, "Failed to delete a file: " + info.getFileName()); } }
/** 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(); } }