Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a097209f authored by Sergey Nikolaienkov's avatar Sergey Nikolaienkov Committed by Android (Google) Code Review
Browse files

Merge "Update CMD association flow."

parents 2a70bcca 9a2b8a16
Loading
Loading
Loading
Loading
+89 −104
Original line number Diff line number Diff line
@@ -20,12 +20,15 @@ import static android.Manifest.permission.REQUEST_COMPANION_SELF_MANAGED;

import static com.android.internal.util.CollectionUtils.emptyIfNull;

import static java.util.Objects.requireNonNull;

import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.StringDef;
import android.annotation.SystemApi;
import android.annotation.UserIdInt;
import android.compat.annotation.UnsupportedAppUsage;
import android.os.Build;
import android.os.Parcel;
@@ -52,12 +55,11 @@ import java.util.Objects;
 * device to be shown instead of a list to choose from
 */
@DataClass(
        genConstructor = false,
        genToString = true,
        genEqualsHashCode = true,
        genHiddenGetters = true,
        genParcelable = true,
        genHiddenConstructor = true,
        genBuilder = false,
        genConstDefs = false)
public final class AssociationRequest implements Parcelable {
    /**
@@ -151,39 +153,75 @@ public final class AssociationRequest implements Parcelable {
    private final boolean mForceConfirmation;

    /**
     * The app package making the request.
     *
     * The app package name of the application the association will belong to.
     * Populated by the system.
     *
     * @hide
     */
    private @Nullable String mCallingPackage;
    private @Nullable String mPackageName;

    /**
     * The UserId of the user the association will belong to.
     * Populated by the system.
     * @hide
     */
    private @UserIdInt int mUserId;

    /**
     * The user-readable description of the device profile's privileges.
     *
     * Populated by the system.
     *
     * @hide
     */
    private @Nullable String mDeviceProfilePrivilegesDescription;

    /**
     * The time at which his request was created
     *
     * @hide
     */
    private long mCreationTime;
    private final long mCreationTime;

    /**
     * Whether the user-prompt may be skipped once the device is found.
     *
     * Populated by the system.
     *
     * @hide
     */
    private boolean mSkipPrompt;

    /**
     * Creates a new AssociationRequest.
     *
     * @param singleDevice
     *   Whether only a single device should match the provided filter.
     *
     *   When scanning for a single device with a specific {@link BluetoothDeviceFilter} mac
     *   address, bonded devices are also searched among. This allows to obtain the necessary app
     *   privileges even if the device is already paired.
     * @param deviceFilters
     *   If set, only devices matching either of the given filters will be shown to the user
     * @param deviceProfile
     *   Profile of the device.
     * @param displayName
     *   The Display name of the device to be shown in the CDM confirmation UI. Must be non-null for
     *   "self-managed" association.
     * @param selfManaged
     *   Whether the association is to be managed by the companion application.
     */
    private AssociationRequest(
            boolean singleDevice,
            @NonNull List<DeviceFilter<?>> deviceFilters,
            @Nullable @DeviceProfile String deviceProfile,
            @Nullable CharSequence displayName,
            boolean selfManaged,
            boolean forceConfirmation) {
        mSingleDevice = singleDevice;
        mDeviceFilters = requireNonNull(deviceFilters);
        mDeviceProfile = deviceProfile;
        mDisplayName = displayName;
        mSelfManaged = selfManaged;
        mForceConfirmation = forceConfirmation;

        mCreationTime = System.currentTimeMillis();
    }

    /**
     * @return profile of the companion device.
     */
@@ -237,8 +275,13 @@ public final class AssociationRequest implements Parcelable {
    }

    /** @hide */
    public void setCallingPackage(@NonNull String pkg) {
        mCallingPackage = pkg;
    public void setPackageName(@NonNull String packageName) {
        mPackageName = packageName;
    }

    /** @hide */
    public void setUserId(@UserIdInt int userId) {
        mUserId = userId;
    }

    /** @hide */
@@ -248,7 +291,7 @@ public final class AssociationRequest implements Parcelable {

    /** @hide */
    public void setSkipPrompt(boolean value) {
        mSkipPrompt = true;
        mSkipPrompt = value;
    }

    /** @hide */
@@ -258,10 +301,6 @@ public final class AssociationRequest implements Parcelable {
        return mDeviceFilters;
    }

    private void onConstructed() {
        mCreationTime = System.currentTimeMillis();
    }

    /**
     * A builder for {@link AssociationRequest}
     */
@@ -325,7 +364,7 @@ public final class AssociationRequest implements Parcelable {
        @NonNull
        public Builder setDisplayName(@NonNull CharSequence displayName) {
            checkNotUsed();
            mDisplayName = Objects.requireNonNull(displayName);
            mDisplayName = requireNonNull(displayName);
            return this;
        }

@@ -372,15 +411,13 @@ public final class AssociationRequest implements Parcelable {
                        + "provide the display name of the device");
            }
            return new AssociationRequest(mSingleDevice, emptyIfNull(mDeviceFilters),
                    mDeviceProfile, mDisplayName, mSelfManaged, mForceConfirmation,
                    null, null, -1L, false);
                    mDeviceProfile, mDisplayName, mSelfManaged, mForceConfirmation);
        }
    }





    // Code below generated by codegen v1.0.23.
    //
    // DO NOT MODIFY!
@@ -395,88 +432,29 @@ public final class AssociationRequest implements Parcelable {


    /**
     * Creates a new AssociationRequest.
     *
     * @param singleDevice
     *   Whether only a single device should match the provided filter.
     *
     *   When scanning for a single device with a specific {@link BluetoothDeviceFilter} mac
     *   address, bonded devices are also searched among. This allows to obtain the necessary app
     *   privileges even if the device is already paired.
     * @param deviceFilters
     *   If set, only devices matching either of the given filters will be shown to the user
     * @param deviceProfile
     *   Profile of the device.
     * @param displayName
     *   The Display name of the device to be shown in the CDM confirmation UI. Must be non-null for
     *   "self-managed" association.
     * @param selfManaged
     *   Whether the association is to be managed by the companion application.
     * @param forceConfirmation
     *   Indicates that the application would prefer the CompanionDeviceManager to collect an explicit
     *   confirmation from the user before creating an association, even if such confirmation is not
     *   required.
     * @param callingPackage
     *   The app package making the request.
     *
     *   Populated by the system.
     * @param deviceProfilePrivilegesDescription
     *   The user-readable description of the device profile's privileges.
     *
     * The app package name of the application the association will belong to.
     * Populated by the system.
     * @param creationTime
     *   The time at which his request was created
     * @param skipPrompt
     *   Whether the user-prompt may be skipped once the device is found.
     *
     *   Populated by the system.
     * @hide
     */
    @DataClass.Generated.Member
    public AssociationRequest(
            boolean singleDevice,
            @NonNull List<DeviceFilter<?>> deviceFilters,
            @Nullable @DeviceProfile String deviceProfile,
            @Nullable CharSequence displayName,
            boolean selfManaged,
            boolean forceConfirmation,
            @Nullable String callingPackage,
            @Nullable String deviceProfilePrivilegesDescription,
            long creationTime,
            boolean skipPrompt) {
        this.mSingleDevice = singleDevice;
        this.mDeviceFilters = deviceFilters;
        com.android.internal.util.AnnotationValidations.validate(
                NonNull.class, null, mDeviceFilters);
        this.mDeviceProfile = deviceProfile;
        com.android.internal.util.AnnotationValidations.validate(
                DeviceProfile.class, null, mDeviceProfile);
        this.mDisplayName = displayName;
        this.mSelfManaged = selfManaged;
        this.mForceConfirmation = forceConfirmation;
        this.mCallingPackage = callingPackage;
        this.mDeviceProfilePrivilegesDescription = deviceProfilePrivilegesDescription;
        this.mCreationTime = creationTime;
        this.mSkipPrompt = skipPrompt;

        onConstructed();
    public @Nullable String getPackageName() {
        return mPackageName;
    }

    /**
     * The app package making the request.
     *
     * The UserId of the user the association will belong to.
     * Populated by the system.
     *
     * @hide
     */
    @DataClass.Generated.Member
    public @Nullable String getCallingPackage() {
        return mCallingPackage;
    public @UserIdInt int getUserId() {
        return mUserId;
    }

    /**
     * The user-readable description of the device profile's privileges.
     *
     * Populated by the system.
     *
     * @hide
@@ -498,7 +476,6 @@ public final class AssociationRequest implements Parcelable {

    /**
     * Whether the user-prompt may be skipped once the device is found.
     *
     * Populated by the system.
     *
     * @hide
@@ -521,7 +498,8 @@ public final class AssociationRequest implements Parcelable {
                "displayName = " + mDisplayName + ", " +
                "selfManaged = " + mSelfManaged + ", " +
                "forceConfirmation = " + mForceConfirmation + ", " +
                "callingPackage = " + mCallingPackage + ", " +
                "packageName = " + mPackageName + ", " +
                "userId = " + mUserId + ", " +
                "deviceProfilePrivilegesDescription = " + mDeviceProfilePrivilegesDescription + ", " +
                "creationTime = " + mCreationTime + ", " +
                "skipPrompt = " + mSkipPrompt +
@@ -547,7 +525,8 @@ public final class AssociationRequest implements Parcelable {
                && Objects.equals(mDisplayName, that.mDisplayName)
                && mSelfManaged == that.mSelfManaged
                && mForceConfirmation == that.mForceConfirmation
                && Objects.equals(mCallingPackage, that.mCallingPackage)
                && Objects.equals(mPackageName, that.mPackageName)
                && mUserId == that.mUserId
                && Objects.equals(mDeviceProfilePrivilegesDescription, that.mDeviceProfilePrivilegesDescription)
                && mCreationTime == that.mCreationTime
                && mSkipPrompt == that.mSkipPrompt;
@@ -566,7 +545,8 @@ public final class AssociationRequest implements Parcelable {
        _hash = 31 * _hash + Objects.hashCode(mDisplayName);
        _hash = 31 * _hash + Boolean.hashCode(mSelfManaged);
        _hash = 31 * _hash + Boolean.hashCode(mForceConfirmation);
        _hash = 31 * _hash + Objects.hashCode(mCallingPackage);
        _hash = 31 * _hash + Objects.hashCode(mPackageName);
        _hash = 31 * _hash + mUserId;
        _hash = 31 * _hash + Objects.hashCode(mDeviceProfilePrivilegesDescription);
        _hash = 31 * _hash + Long.hashCode(mCreationTime);
        _hash = 31 * _hash + Boolean.hashCode(mSkipPrompt);
@@ -583,16 +563,17 @@ public final class AssociationRequest implements Parcelable {
        if (mSingleDevice) flg |= 0x1;
        if (mSelfManaged) flg |= 0x10;
        if (mForceConfirmation) flg |= 0x20;
        if (mSkipPrompt) flg |= 0x200;
        if (mSkipPrompt) flg |= 0x400;
        if (mDeviceProfile != null) flg |= 0x4;
        if (mDisplayName != null) flg |= 0x8;
        if (mCallingPackage != null) flg |= 0x40;
        if (mDeviceProfilePrivilegesDescription != null) flg |= 0x80;
        if (mPackageName != null) flg |= 0x40;
        if (mDeviceProfilePrivilegesDescription != null) flg |= 0x100;
        dest.writeInt(flg);
        dest.writeParcelableList(mDeviceFilters, flags);
        if (mDeviceProfile != null) dest.writeString(mDeviceProfile);
        if (mDisplayName != null) dest.writeCharSequence(mDisplayName);
        if (mCallingPackage != null) dest.writeString(mCallingPackage);
        if (mPackageName != null) dest.writeString(mPackageName);
        dest.writeInt(mUserId);
        if (mDeviceProfilePrivilegesDescription != null) dest.writeString(mDeviceProfilePrivilegesDescription);
        dest.writeLong(mCreationTime);
    }
@@ -612,13 +593,14 @@ public final class AssociationRequest implements Parcelable {
        boolean singleDevice = (flg & 0x1) != 0;
        boolean selfManaged = (flg & 0x10) != 0;
        boolean forceConfirmation = (flg & 0x20) != 0;
        boolean skipPrompt = (flg & 0x200) != 0;
        boolean skipPrompt = (flg & 0x400) != 0;
        List<DeviceFilter<?>> deviceFilters = new ArrayList<>();
        in.readParcelableList(deviceFilters, DeviceFilter.class.getClassLoader());
        String deviceProfile = (flg & 0x4) == 0 ? null : in.readString();
        CharSequence displayName = (flg & 0x8) == 0 ? null : (CharSequence) in.readCharSequence();
        String callingPackage = (flg & 0x40) == 0 ? null : in.readString();
        String deviceProfilePrivilegesDescription = (flg & 0x80) == 0 ? null : in.readString();
        String packageName = (flg & 0x40) == 0 ? null : in.readString();
        int userId = in.readInt();
        String deviceProfilePrivilegesDescription = (flg & 0x100) == 0 ? null : in.readString();
        long creationTime = in.readLong();

        this.mSingleDevice = singleDevice;
@@ -631,12 +613,15 @@ public final class AssociationRequest implements Parcelable {
        this.mDisplayName = displayName;
        this.mSelfManaged = selfManaged;
        this.mForceConfirmation = forceConfirmation;
        this.mCallingPackage = callingPackage;
        this.mPackageName = packageName;
        this.mUserId = userId;
        com.android.internal.util.AnnotationValidations.validate(
                UserIdInt.class, null, mUserId);
        this.mDeviceProfilePrivilegesDescription = deviceProfilePrivilegesDescription;
        this.mCreationTime = creationTime;
        this.mSkipPrompt = skipPrompt;

        onConstructed();
        // onConstructed(); // You can define this method to get a callback
    }

    @DataClass.Generated.Member
@@ -654,10 +639,10 @@ public final class AssociationRequest implements Parcelable {
    };

    @DataClass.Generated(
            time = 1638368698639L,
            time = 1638962248060L,
            codegenVersion = "1.0.23",
            sourceFile = "frameworks/base/core/java/android/companion/AssociationRequest.java",
            inputSignatures = "public static final  java.lang.String DEVICE_PROFILE_WATCH\npublic static final @android.annotation.RequiresPermission @android.annotation.SystemApi java.lang.String DEVICE_PROFILE_APP_STREAMING\npublic static final @android.annotation.RequiresPermission @android.annotation.SystemApi java.lang.String DEVICE_PROFILE_AUTOMOTIVE_PROJECTION\nprivate final  boolean mSingleDevice\nprivate final @com.android.internal.util.DataClass.PluralOf(\"deviceFilter\") @android.annotation.NonNull java.util.List<android.companion.DeviceFilter<?>> mDeviceFilters\nprivate final @android.annotation.Nullable @android.companion.AssociationRequest.DeviceProfile java.lang.String mDeviceProfile\nprivate final @android.annotation.Nullable java.lang.CharSequence mDisplayName\nprivate final  boolean mSelfManaged\nprivate final  boolean mForceConfirmation\nprivate @android.annotation.Nullable java.lang.String mCallingPackage\nprivate @android.annotation.Nullable java.lang.String mDeviceProfilePrivilegesDescription\nprivate  long mCreationTime\nprivate  boolean mSkipPrompt\npublic @android.annotation.Nullable @android.companion.AssociationRequest.DeviceProfile java.lang.String getDeviceProfile()\npublic @android.annotation.Nullable java.lang.CharSequence getDisplayName()\npublic @android.annotation.SystemApi @android.annotation.RequiresPermission boolean isSelfManaged()\npublic @android.annotation.SystemApi @android.annotation.RequiresPermission boolean isForceConfirmation()\npublic  boolean isSingleDevice()\npublic  void setCallingPackage(java.lang.String)\npublic  void setDeviceProfilePrivilegesDescription(java.lang.String)\npublic  void setSkipPrompt(boolean)\npublic @android.annotation.NonNull @android.compat.annotation.UnsupportedAppUsage java.util.List<android.companion.DeviceFilter<?>> getDeviceFilters()\nprivate  void onConstructed()\nclass AssociationRequest extends java.lang.Object implements [android.os.Parcelable]\nprivate  boolean mSingleDevice\nprivate @android.annotation.Nullable java.util.ArrayList<android.companion.DeviceFilter<?>> mDeviceFilters\nprivate @android.annotation.Nullable java.lang.String mDeviceProfile\nprivate @android.annotation.Nullable java.lang.CharSequence mDisplayName\nprivate  boolean mSelfManaged\nprivate  boolean mForceConfirmation\npublic @android.annotation.NonNull android.companion.AssociationRequest.Builder setSingleDevice(boolean)\npublic @android.annotation.NonNull android.companion.AssociationRequest.Builder addDeviceFilter(android.companion.DeviceFilter<?>)\npublic @android.annotation.NonNull android.companion.AssociationRequest.Builder setDeviceProfile(java.lang.String)\npublic @android.annotation.NonNull android.companion.AssociationRequest.Builder setDisplayName(java.lang.CharSequence)\npublic @android.annotation.SystemApi @android.annotation.RequiresPermission @android.annotation.NonNull android.companion.AssociationRequest.Builder setSelfManaged(boolean)\npublic @android.annotation.SystemApi @android.annotation.RequiresPermission @android.annotation.NonNull android.companion.AssociationRequest.Builder setForceConfirmation(boolean)\npublic @android.annotation.NonNull @java.lang.Override android.companion.AssociationRequest build()\nclass Builder extends android.provider.OneTimeUseBuilder<android.companion.AssociationRequest> implements []\n@com.android.internal.util.DataClass(genToString=true, genEqualsHashCode=true, genHiddenGetters=true, genParcelable=true, genHiddenConstructor=true, genBuilder=false, genConstDefs=false)")
            inputSignatures = "public static final  java.lang.String DEVICE_PROFILE_WATCH\npublic static final @android.annotation.RequiresPermission @android.annotation.SystemApi java.lang.String DEVICE_PROFILE_APP_STREAMING\npublic static final @android.annotation.RequiresPermission @android.annotation.SystemApi java.lang.String DEVICE_PROFILE_AUTOMOTIVE_PROJECTION\nprivate final  boolean mSingleDevice\nprivate final @com.android.internal.util.DataClass.PluralOf(\"deviceFilter\") @android.annotation.NonNull java.util.List<android.companion.DeviceFilter<?>> mDeviceFilters\nprivate final @android.annotation.Nullable @android.companion.AssociationRequest.DeviceProfile java.lang.String mDeviceProfile\nprivate final @android.annotation.Nullable java.lang.CharSequence mDisplayName\nprivate final  boolean mSelfManaged\nprivate final  boolean mForceConfirmation\nprivate @android.annotation.Nullable java.lang.String mPackageName\nprivate @android.annotation.UserIdInt int mUserId\nprivate @android.annotation.Nullable java.lang.String mDeviceProfilePrivilegesDescription\nprivate final  long mCreationTime\nprivate  boolean mSkipPrompt\npublic @android.annotation.Nullable @android.companion.AssociationRequest.DeviceProfile java.lang.String getDeviceProfile()\npublic @android.annotation.Nullable java.lang.CharSequence getDisplayName()\npublic @android.annotation.SystemApi @android.annotation.RequiresPermission boolean isSelfManaged()\npublic @android.annotation.SystemApi @android.annotation.RequiresPermission boolean isForceConfirmation()\npublic  boolean isSingleDevice()\npublic  void setPackageName(java.lang.String)\npublic  void setUserId(int)\npublic  void setDeviceProfilePrivilegesDescription(java.lang.String)\npublic  void setSkipPrompt(boolean)\npublic @android.annotation.NonNull @android.compat.annotation.UnsupportedAppUsage java.util.List<android.companion.DeviceFilter<?>> getDeviceFilters()\nclass AssociationRequest extends java.lang.Object implements [android.os.Parcelable]\nprivate  boolean mSingleDevice\nprivate @android.annotation.Nullable java.util.ArrayList<android.companion.DeviceFilter<?>> mDeviceFilters\nprivate @android.annotation.Nullable java.lang.String mDeviceProfile\nprivate @android.annotation.Nullable java.lang.CharSequence mDisplayName\nprivate  boolean mSelfManaged\nprivate  boolean mForceConfirmation\npublic @android.annotation.NonNull android.companion.AssociationRequest.Builder setSingleDevice(boolean)\npublic @android.annotation.NonNull android.companion.AssociationRequest.Builder addDeviceFilter(android.companion.DeviceFilter<?>)\npublic @android.annotation.NonNull android.companion.AssociationRequest.Builder setDeviceProfile(java.lang.String)\npublic @android.annotation.NonNull android.companion.AssociationRequest.Builder setDisplayName(java.lang.CharSequence)\npublic @android.annotation.SystemApi @android.annotation.RequiresPermission @android.annotation.NonNull android.companion.AssociationRequest.Builder setSelfManaged(boolean)\npublic @android.annotation.SystemApi @android.annotation.RequiresPermission @android.annotation.NonNull android.companion.AssociationRequest.Builder setForceConfirmation(boolean)\npublic @android.annotation.NonNull @java.lang.Override android.companion.AssociationRequest build()\nclass Builder extends android.provider.OneTimeUseBuilder<android.companion.AssociationRequest> implements []\n@com.android.internal.util.DataClass(genConstructor=false, genToString=true, genEqualsHashCode=true, genHiddenGetters=true, genParcelable=true, genConstDefs=false)")
    @Deprecated
    private void __metadata() {}

+8 −18
Original line number Diff line number Diff line
@@ -19,10 +19,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.android.companiondevicemanager">

    <permission
        android:name="com.android.companiondevicemanager.permission.BIND"
        android:protectionLevel="signature" />

    <uses-permission android:name="android.permission.BLUETOOTH"/>
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
    <uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE"/>
@@ -43,23 +39,17 @@
        android:forceQueryable="true"
        android:supportsRtl="true">

        <service
            android:name=".CompanionDeviceDiscoveryService"
            android:permission="android.permission.BIND_COMPANION_DEVICE_MANAGER_SERVICE"
            android:exported="true">
        </service>

        <activity
            android:name=".CompanionDeviceActivity"
            android:theme="@style/ChooserActivity"
            android:exported="true"
            android:launchMode="singleInstance"
            android:excludeFromRecents="true"
            android:permission="android.permission.BIND_COMPANION_DEVICE_MANAGER_SERVICE"
            android:exported="true">
            <!--TODO include url scheme filter similar to PrintSpooler -->
            <intent-filter>
                <action android:name="android.companiondevice.START_DISCOVERY" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
            android:theme="@style/ChooserActivity"/>

        <service
            android:name=".CompanionDeviceDiscoveryService"
            android:exported="false" />

    </application>

+81 −0

File added.

Preview size limit exceeded, changes collapsed.

+0 −43
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2017 The Android Open Source Project

     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at

          http://www.apache.org/licenses/LICENSE-2.0

     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations under the License.
-->


<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/buttons"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:layout_alignParentBottom="true"
    android:layout_alignParentEnd="true"
    android:gravity="end"
>
    <Button
        android:id="@+id/button_cancel"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/consent_no"
        android:textColor="?android:attr/textColorSecondary"
        style="@android:style/Widget.Material.Button.Borderless.Colored"
    />
    <Button
        android:id="@+id/button_pair"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/consent_yes"
        style="@android:style/Widget.Material.Button.Borderless.Colored"
    />
</LinearLayout>
 No newline at end of file
+0 −39

File deleted.

Preview size limit exceeded, changes collapsed.

Loading