Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion core/java/android/content/ClipDescription.java
Original file line number Diff line number Diff line change
Expand Up @@ -423,8 +423,10 @@ public boolean isStyledText() {
* Sets whether the associated {@link ClipData} contains styled text in its first item. This
* should be called when this description is associated with clip data or when the first item
* is added to the associated clip data.
*
* @hide
*/
void setIsStyledText(boolean isStyledText) {
public void setIsStyledText(boolean isStyledText) {
mIsStyledText = isStyledText;
}

Expand Down
4 changes: 4 additions & 0 deletions core/java/android/content/pm/GosPackageStateFlag.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ public interface GosPackageStateFlag {
/** @hide */ int BLOCK_PLAY_INTEGRITY_API = 28;
/** @hide */ int USE_EXEC_SPAWNING_NON_DEFAULT = 29;
/** @hide */ int USE_EXEC_SPAWNING = 30;
/** @hide */ int ALLOW_CLIPBOARD_READ_NON_DEFAULT = 31;
/** @hide */ int ALLOW_CLIPBOARD_READ = 32;

/** @hide */
@IntDef(value = {
Expand Down Expand Up @@ -68,6 +70,8 @@ public interface GosPackageStateFlag {
BLOCK_PLAY_INTEGRITY_API,
USE_EXEC_SPAWNING_NON_DEFAULT,
USE_EXEC_SPAWNING,
ALLOW_CLIPBOARD_READ_NON_DEFAULT,
ALLOW_CLIPBOARD_READ,
})
@Retention(RetentionPolicy.SOURCE)
@interface Enum {}
Expand Down
1 change: 1 addition & 0 deletions core/java/android/ext/SettingsIntents.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ public class SettingsIntents {
public static final String APP_MEMORY_DYN_CODE_LOADING = "android.settings.OPEN_APP_MEMORY_DYN_CODE_LOADING_SETTINGS";
public static final String APP_STORAGE_DYN_CODE_LOADING = "android.settings.OPEN_APP_STORAGE_DYN_CODE_LOADING_SETTINGS";
public static final String APP_MANAGE_PLAY_INTEGRITY_API = "android.settings.OPEN_APP_MANAGE_PLAY_INTEGRITY_API_SETTINGS";
public static final String APP_CLIPBOARD_READ = "android.settings.OPEN_APP_CLIPBOARD_READ_SETTINGS";

public static Intent getAppIntent(Context ctx, String action, String pkgName) {
var i = new Intent(action);
Expand Down
8 changes: 8 additions & 0 deletions core/java/android/ext/settings/ExtSettings.java
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,14 @@ public class ExtSettings {
public static final BoolSetting DISALLOW_DELAYED_LOCKING_ON_USER_STOP = new BoolSetting(
Setting.Scope.PER_USER, Settings.Secure.DISALLOW_DELAYED_LOCKING_ON_USER_STOP, false);

public static final BoolSetting SHOW_CLIPBOARD_ACCESS_DENIAL_NOTIFICATIONS = new BoolSetting(
Setting.Scope.PER_USER,
Settings.Secure.CLIPBOARD_SHOW_ACCESS_DENIAL_NOTIFICATIONS, true);

public static final BoolSetting ALLOW_CLIPBOARD_READ_BY_DEFAULT = new BoolSetting(
Setting.Scope.GLOBAL, Settings.Global.ALLOW_CLIPBOARD_READ_BY_DEFAULT,
defaultBool(R.bool.setting_default_allow_clipboard_read));

private ExtSettings() {}

public static Function<Context, Boolean> defaultBool(@BoolRes int res) {
Expand Down
13 changes: 8 additions & 5 deletions core/java/android/ext/settings/app/AppSwitch.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ public abstract class AppSwitch {
public static final int IR_EXPLOIT_PROTECTION_COMPAT_MODE = 6;
public static final int IR_REQUIRED_BY_HARDENED_MALLOC = 7;
public static final int IR_REQUIRED_BY_ZYGOTE_SPAWNING = 8;
public static final int IR_IS_DEFAULT_IME = 9;

// default value reasons
public static final int DVR_UNKNOWN = 0;
Expand Down Expand Up @@ -127,10 +128,7 @@ public final boolean get(Context ctx, int userId, ApplicationInfo appInfo,
si.isUsingDefaultValue = true;
res = getDefaultValue(ctx, userId, appInfo, ps, si);
} else {
res = ps.hasFlag(gosPsFlag);
if (gosPsFlagInverted) {
res = !res;
}
res = getNonDefaultValue(ps);
}

return res;
Expand All @@ -148,10 +146,15 @@ public final void set(GosPackageState.Editor ed, boolean on) {
}
}

private boolean isUsingDefaultValue(GosPackageState ps) {
protected final boolean isUsingDefaultValue(GosPackageState ps) {
return gosPsFlagNonDefault != 0 && !ps.hasFlag(gosPsFlagNonDefault);
}

protected final boolean getNonDefaultValue(GosPackageState ps) {
final boolean value = ps.hasFlag(gosPsFlag);
return gosPsFlagInverted ? !value : value;
}

public final void setUseDefaultValue(GosPackageState.Editor ed) {
ed.clearFlag(gosPsFlagNonDefault);
ed.clearFlag(gosPsFlag);
Expand Down
76 changes: 76 additions & 0 deletions core/java/android/ext/settings/app/AswAllowClipboardRead.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package android.ext.settings.app;

import android.content.ComponentName;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.GosPackageState;
import android.content.pm.GosPackageStateFlag;
import android.ext.settings.ExtSettings;
import android.provider.Settings;
import android.text.TextUtils;

/** @hide */
public class AswAllowClipboardRead extends AppSwitch {
public static final AswAllowClipboardRead I = new AswAllowClipboardRead();

private AswAllowClipboardRead() {
gosPsFlag = GosPackageStateFlag.ALLOW_CLIPBOARD_READ;
gosPsFlagNonDefault = GosPackageStateFlag.ALLOW_CLIPBOARD_READ_NON_DEFAULT;
}

@Override
public Boolean getImmutableValue(Context ctx, int userId, ApplicationInfo appInfo,
GosPackageState ps, StateInfo si) {
final int reason = getImmutabilityReason(appInfo.isSystemApp(),
isDefaultIme(ctx, userId, appInfo.packageName));
if (reason != IR_UNKNOWN) {
si.immutabilityReason = reason;
return true;
}

return null;
}

@Override
protected boolean getDefaultValueInner(Context ctx, int userId, ApplicationInfo appInfo,
GosPackageState ps, StateInfo si) {
si.defaultValueReason = DVR_DEFAULT_SETTING;
return getDefaultValue(ctx, userId);
}

public boolean get(Context ctx, int userId, boolean isSystemApp, boolean isDefaultIme,
GosPackageState ps) {
if (getImmutabilityReason(isSystemApp, isDefaultIme) != IR_UNKNOWN) {
return true;
}
return isUsingDefaultValue(ps)
? getDefaultValue(ctx, userId)
: getNonDefaultValue(ps);
}

private static int getImmutabilityReason(boolean isSystemApp, boolean isDefaultIme) {
if (isSystemApp) {
return IR_IS_SYSTEM_APP;
}
return isDefaultIme ? IR_IS_DEFAULT_IME : IR_UNKNOWN;
}

private static boolean getDefaultValue(Context ctx, int userId) {
return ExtSettings.ALLOW_CLIPBOARD_READ_BY_DEFAULT.get(ctx, userId);
}

// based on ClipboardService#isDefaultIme
private boolean isDefaultIme(Context ctx, int userId, String packageName) {
String defaultIme = Settings.Secure.getStringForUser(ctx.getContentResolver(),
Settings.Secure.DEFAULT_INPUT_METHOD, userId);
if (!TextUtils.isEmpty(defaultIme)) {
final ComponentName imeComponent = ComponentName.unflattenFromString(defaultIme);
if (imeComponent == null) {
return false;
}
final String imPkg = imeComponent.getPackageName();
return imPkg.equals(packageName);
}
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,11 @@ public boolean isSameConnection(@NonNull IRemoteInputConnection connection) {
return mConnection.asBinder() == connection.asBinder();
}

@NonNull
IBinder getConnectionToken() {
return mConnection.asBinder();
}

@NonNull
InputConnectionCommandHeader createHeader() {
return new InputConnectionCommandHeader(mSessionId);
Expand Down
5 changes: 5 additions & 0 deletions core/java/android/inputmethodservice/InputMethodService.java
Original file line number Diff line number Diff line change
Expand Up @@ -4482,6 +4482,11 @@ private void exposeContentInternal(@NonNull InputContentInfo inputContentInfo,
inputContentInfo.setUriToken(uriToken);
}

@Override
public void onPasteAction(@NonNull IBinder inputConnectionToken) {
mPrivOps.onPasteAction(inputConnectionToken);
}

/**
* {@inheritDoc}
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Bundle;
import android.os.IBinder;
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputContentInfo;

Expand Down Expand Up @@ -61,6 +62,9 @@ default void exposeContent(@NonNull InputContentInfo inputContentInfo,
default void notifyUserActionIfNecessary() {
}

default void onPasteAction(@NonNull IBinder inputConnectionToken) {
}

/**
* Called when the system is asking the IME to dump its information for debugging.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,13 @@ public boolean performEditorAction(int actionCode) {

@AnyThread
public boolean performContextMenuAction(int id) {
if (id == android.R.id.paste || id == android.R.id.pasteAsPlainText) {
final InputMethodServiceInternal imsInternal = mImsInternal.getAndWarnIfNull();
if (imsInternal != null) {
// Process authorization before dispatch because the app may read immediately.
imsInternal.onPasteAction(mInvoker.getConnectionToken());
}
}
return mInvoker.performContextMenuAction(id);
}

Expand Down
9 changes: 9 additions & 0 deletions core/java/android/provider/Settings.java
Original file line number Diff line number Diff line change
Expand Up @@ -7519,6 +7519,11 @@ public static final class Secure extends NameValueTable {
@Protected(readWrite = KnownSystemPackage.SETTINGS)
public static final String CROSS_PROFILE_CLIPBOARD_ACCESS = "cross_profile_clipboard_access";

/** @hide */
@Protected(readWrite = KnownSystemPackage.SETTINGS)
public static final String CLIPBOARD_SHOW_ACCESS_DENIAL_NOTIFICATIONS =
"clipboard_show_access_denial_notifications";

/** @hide */
@Protected(readWrite = KnownSystemPackage.SETTINGS)
public static final String DISALLOW_DELAYED_LOCKING_ON_USER_STOP = "disallow_delayed_locking_on_user_stop";
Expand Down Expand Up @@ -14523,6 +14528,10 @@ public static final class Global extends NameValueTable {
@Protected(restrictReads = false, readWrite = KnownSystemPackage.SETTINGS)
public static final String CERT_TRANSPARENCY_DOWNLOADER = "cert_transparency_downloader";

/** @hide */
@Protected(readWrite = KnownSystemPackage.SETTINGS)
public static final String ALLOW_CLIPBOARD_READ_BY_DEFAULT = "allow_clipboard_read";

// ExtSettings END

// NOTE: If you add new settings here, be sure to add them to
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,5 @@ import android.os.IBinder;
interface ISelectionToolbarRenderServiceCallback {
oneway void transferTouch(in IBinder source, in IBinder target);

void onPasteAction(int uid);
void onPasteAction(int uid, in IBinder hostInputToken);
}
Original file line number Diff line number Diff line change
Expand Up @@ -156,14 +156,14 @@ protected void transferTouch(@NonNull IBinder source, @NonNull IBinder target) {
}
}

protected void onPasteAction(int uid) {
protected void onPasteAction(int uid, IBinder hostInputToken) {
final ISelectionToolbarRenderServiceCallback callback = mServiceCallback;
if (callback == null) {
Log.e(TAG, "onPasteAction(): no server callback");
return;
}
try {
callback.onPasteAction(uid);
callback.onPasteAction(uid, hostInputToken);
} catch (RemoteException e) {
Log.e(TAG, "Failed to notify onPasteAction", e);
}
Expand Down Expand Up @@ -264,6 +264,6 @@ public interface OnPasteActionCallback {
/**
* Notify the service to the paste action.
*/
void onPasteAction(int uid);
void onPasteAction(int uid, IBinder hostInputToken);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,5 @@ oneway interface IInputMethodPrivilegedOperations {
void switchKeyboardLayoutAsync(int direction);
void setHandwritingSurfaceNotTouchable(boolean notTouchable);
void setHandwritingTouchableRegion(in Region region);
void onPasteAction(in IBinder inputConnectionToken, in AndroidFuture future /* T=Void */);
}
Original file line number Diff line number Diff line change
Expand Up @@ -474,4 +474,24 @@ public void switchKeyboardLayoutAsync(int direction) {
throw e.rethrowFromSystemServer();
}
}

/**
* Calls {@link IInputMethodPrivilegedOperations#onPasteAction(IBinder, AndroidFuture)} and
* waits for system server to process authorization before the caller dispatches the paste
* action.
*/
@AnyThread
public void onPasteAction(@NonNull IBinder inputConnectionToken) {
final IInputMethodPrivilegedOperations ops = mOps.getAndWarnIfNull();
if (ops == null) {
return;
}
try {
final AndroidFuture<Void> future = new AndroidFuture<>();
ops.onPasteAction(inputConnectionToken, future);
CompletableFutureUtil.getResult(future);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
}
3 changes: 3 additions & 0 deletions core/res/res/values/config_ext.xml
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,7 @@
</string-array>
<java-symbol type="array" name="read_additional_security_state_known_signers" />

<bool name="setting_default_allow_clipboard_read">true</bool>
<java-symbol type="bool" name="setting_default_allow_clipboard_read" />

</resources>
4 changes: 4 additions & 0 deletions core/res/res/values/public-ext.xml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@
<public name="config_usb_port_security_applies_to_pogo_pins"/>
<!-- @hide -->
<public name="config_has_alternative_touchscreen_mode"/>
<!-- @hide -->
<public name="setting_default_allow_clipboard_read"/>
</staging-public-group>

<staging-public-group type="drawable" first-id="0x0194f000">
Expand Down Expand Up @@ -135,5 +137,7 @@
<public name="usb_port_security_error_title"/>
<!-- @hide -->
<public name="deprecated_abi_message_grapheneos"/>
<!-- @hide -->
<public name="clipboard_access_blocked"/>
</staging-public-group>
</resources>
3 changes: 3 additions & 0 deletions core/res/res/values/string_ext.xml
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,7 @@
<string name="usb_port_security_error_title">USB-C port security feature has malfunctioned</string>
<java-symbol type="string" name="usb_port_security_error_title" />

<string name="clipboard_access_blocked">%1$s was blocked from accessing your clipboard</string>
<java-symbol type="string" name="clipboard_access_blocked" />

</resources>
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="match_parent"
android:fitsSystemWindows="true">

<android.widget.CustomInputConnectionEditText
android:id="@+id/edittext1"
Expand Down
3 changes: 2 additions & 1 deletion core/tests/coretests/res/layout/activity_text_view.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="match_parent"
android:fitsSystemWindows="true">

<EditText
android:id="@+id/textview"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1264,6 +1264,7 @@ public void testPastePlainText_noMenuItemForPlainText() {
setText("");
onView(withId(R.id.textview)).perform(longClick());

mToolbar.assertFloatingToolbarIsDisplayed();
mToolbar.assertFloatingToolbarDoesNotContainItem(
mActivity.getString(com.android.internal.R.string.paste_as_plain_text));
}
Expand Down
Loading