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

Commit b18a2588 authored by Adrian Roos's avatar Adrian Roos
Browse files

Revert "Create haptic vibration library"

This reverts commit d073d325.

Change-Id: I14531020713c9c2bb1d8360edb69024e4f2fc8fd
Bug: 323853450
parent ba4bf1df
Loading
Loading
Loading
Loading
+0 −11
Original line number Diff line number Diff line
@@ -38,17 +38,6 @@
      ],
      "file_patterns": ["(?i)drm|crypto"]
    },
    {
      "file_patterns": [
        "[^/]*(Ringtone)[^/]*\\.java"
      ],
      "name": "MediaRingtoneTests",
      "options": [
        {"exclude-annotation": "androidx.test.filters.LargeTest"},
        {"exclude-annotation": "androidx.test.filters.FlakyTest"},
        {"exclude-annotation": "org.junit.Ignore"}
      ]
    },
    {
      "file_patterns": [
        "[^/]*(LoudnessCodec)[^/]*\\.java"
+50 −140
Original line number Diff line number Diff line
@@ -16,7 +16,6 @@

package android.media;

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
@@ -36,19 +35,18 @@ import android.content.res.AssetFileDescriptor;
import android.database.Cursor;
import android.database.StaleDataException;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.FileUtils;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.UserManager;
import android.os.vibrator.persistence.VibrationXmlParser;
import android.provider.BaseColumns;
import android.provider.MediaStore;
import android.provider.MediaStore.Audio.AudioColumns;
import android.provider.MediaStore.MediaColumns;
import android.provider.Settings;
import android.provider.Settings.System;
import android.text.TextUtils;
import android.util.Log;

import com.android.internal.database.SortCursor;
@@ -59,8 +57,6 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.List;

@@ -213,29 +209,20 @@ public class RingtoneManager {
    public static final String EXTRA_RINGTONE_PICKED_URI =
            "android.intent.extra.ringtone.PICKED_URI";
    
    /**
     * Declares the allowed types of media for this RingtoneManager.
     * @hide
     */
    @Retention(RetentionPolicy.SOURCE)
    @IntDef(prefix = "MEDIA_", value = {
            Ringtone.MEDIA_SOUND,
            Ringtone.MEDIA_VIBRATION,
    })
    public @interface MediaType {}

    // Make sure the column ordering and then ..._COLUMN_INDEX are in sync
    
    private static final String[] MEDIA_AUDIO_COLUMNS = new String[] {
    private static final String[] INTERNAL_COLUMNS = new String[] {
        MediaStore.Audio.Media._ID,
        MediaStore.Audio.Media.TITLE,
        MediaStore.Audio.Media.TITLE,
        MediaStore.Audio.Media.TITLE_KEY,
    };

    private static final String[] MEDIA_VIBRATION_COLUMNS = new String[]{
            MediaStore.Files.FileColumns._ID,
            MediaStore.Files.FileColumns.TITLE,
    private static final String[] MEDIA_COLUMNS = new String[] {
        MediaStore.Audio.Media._ID,
        MediaStore.Audio.Media.TITLE,
        MediaStore.Audio.Media.TITLE,
        MediaStore.Audio.Media.TITLE_KEY,
    };

    /**
@@ -263,8 +250,6 @@ public class RingtoneManager {
    private Cursor mCursor;

    private int mType = TYPE_RINGTONE;
    @MediaType
    private int mMediaType = Ringtone.MEDIA_SOUND;
    
    /**
     * If a column (item from this list) exists in the Cursor, its value must
@@ -331,41 +316,6 @@ public class RingtoneManager {
        mIncludeParentRingtones = includeParentRingtones;
    }

    /**
     * Sets the media type that will be listed by the RingtoneManager.
     *
     * <p>This method should be called before calling {@link RingtoneManager#getCursor()}.
     *
     * @hide
     */
    public void setMediaType(@MediaType int mediaType) {
        if (mCursor != null) {
            throw new IllegalStateException(
                    "Setting media should be done before calling getCursor().");
        }

        switch (mediaType) {
            case Ringtone.MEDIA_SOUND:
            case Ringtone.MEDIA_VIBRATION:
                mMediaType = mediaType;
                break;
            default:
                throw new IllegalArgumentException("Unsupported media type " + mediaType);
        }
    }

    /**
     * Returns the RingtoneManagers media type.
     *
     * @return the media type.
     * @see #setMediaType
     * @hide
     */
    @MediaType
    public int getMediaType() {
        return mMediaType;
    }

    /**
     * Sets which type(s) of ringtones will be listed by this.
     * 
@@ -503,19 +453,19 @@ public class RingtoneManager {
            return mCursor;
        }

        ArrayList<Cursor> cursors = new ArrayList<>();

        cursors.add(queryMediaStore(/* internal= */ true));
        cursors.add(queryMediaStore(/* internal= */ false));
        ArrayList<Cursor> ringtoneCursors = new ArrayList<Cursor>();
        ringtoneCursors.add(getInternalRingtones());
        ringtoneCursors.add(getMediaRingtones());

        if (mIncludeParentRingtones) {
            Cursor parentRingtonesCursor = getParentProfileRingtones();
            if (parentRingtonesCursor != null) {
                cursors.add(parentRingtonesCursor);
                ringtoneCursors.add(parentRingtonesCursor);
            }
        }
        return mCursor = new SortCursor(cursors.toArray(new Cursor[cursors.size()]),
                getSortOrderForMedia(mMediaType));

        return mCursor = new SortCursor(ringtoneCursors.toArray(new Cursor[ringtoneCursors.size()]),
                MediaStore.Audio.Media.DEFAULT_SORT_ORDER);
    }

    private Cursor getParentProfileRingtones() {
@@ -527,7 +477,9 @@ public class RingtoneManager {
                // We don't need to re-add the internal ringtones for the work profile since
                // they are the same as the personal profile. We just need the external
                // ringtones.
                return queryMediaStore(parentContext, /* internal= */ false);
                final Cursor res = getMediaRingtones(parentContext);
                return new ExternalRingtonesCursorWrapper(res, ContentProvider.maybeAddUserId(
                        MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, parentInfo.id));
            }
        }
        return null;
@@ -549,7 +501,7 @@ public class RingtoneManager {
        Uri positionUri = getRingtoneUri(position);
        if (Ringtone.useRingtoneV2()) {
            mPreviousRingtone = new Ringtone.Builder(
                    mContext, mMediaType, getDefaultAudioAttributes(mType))
                    mContext, Ringtone.MEDIA_SOUND, getDefaultAudioAttributes(mType))
                    .setUri(positionUri)
                    .build();
        } else {
@@ -723,12 +675,10 @@ public class RingtoneManager {
    public static Uri getValidRingtoneUri(Context context) {
        final RingtoneManager rm = new RingtoneManager(context);
        
        Uri uri = getValidRingtoneUriFromCursorAndClose(context,
                rm.queryMediaStore(/* internal= */ true));
        Uri uri = getValidRingtoneUriFromCursorAndClose(context, rm.getInternalRingtones());

        if (uri == null) {
            uri = getValidRingtoneUriFromCursorAndClose(context,
                    rm.queryMediaStore(/* internal= */ false));
            uri = getValidRingtoneUriFromCursorAndClose(context, rm.getMediaRingtones());
        }
        
        return uri;
@@ -749,26 +699,28 @@ public class RingtoneManager {
        }
    }

    private Cursor queryMediaStore(boolean internal) {
        return queryMediaStore(mContext, internal);
    @UnsupportedAppUsage
    private Cursor getInternalRingtones() {
        final Cursor res = query(
                MediaStore.Audio.Media.INTERNAL_CONTENT_URI, INTERNAL_COLUMNS,
                constructBooleanTrueWhereClause(mFilterColumns),
                null, MediaStore.Audio.Media.DEFAULT_SORT_ORDER);
        return new ExternalRingtonesCursorWrapper(res, MediaStore.Audio.Media.INTERNAL_CONTENT_URI);
    }

    private Cursor queryMediaStore(Context context, boolean internal) {
        Uri contentUri = getContentUriForMedia(mMediaType, internal);
        String[] columns =
                mMediaType == Ringtone.MEDIA_VIBRATION ? MEDIA_VIBRATION_COLUMNS
                        : MEDIA_AUDIO_COLUMNS;
        String whereClause = getWhereClauseForMedia(mMediaType, mFilterColumns);
        String sortOrder = getSortOrderForMedia(mMediaType);

        Cursor cursor = query(contentUri, columns, whereClause, /* selectionArgs= */ null,
                sortOrder, context);

        if (context.getUserId() != mContext.getUserId()) {
            contentUri = ContentProvider.maybeAddUserId(contentUri, context.getUserId());
    private Cursor getMediaRingtones() {
        final Cursor res = getMediaRingtones(mContext);
        return new ExternalRingtonesCursorWrapper(res, MediaStore.Audio.Media.EXTERNAL_CONTENT_URI);
    }

        return new ExternalRingtonesCursorWrapper(cursor, contentUri);
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
    private Cursor getMediaRingtones(Context context) {
        // MediaStore now returns ringtones on other storage devices, even when
        // we don't have storage or audio permissions
        return query(
                MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, MEDIA_COLUMNS,
                constructBooleanTrueWhereClause(mFilterColumns), null,
                MediaStore.Audio.Media.DEFAULT_SORT_ORDER, context);
    }

    private void setFilterColumnsList(int type) {
@@ -788,56 +740,6 @@ public class RingtoneManager {
        }
    }
    
    /**
     * Returns the sort order for the specified media.
     *
     * @param media The RingtoneManager media type.
     * @return The sort order column.
     */
    private static String getSortOrderForMedia(@MediaType int media) {
        return media == Ringtone.MEDIA_VIBRATION ? MediaStore.Files.FileColumns.TITLE
                : MediaStore.Audio.Media.DEFAULT_SORT_ORDER;
    }

    /**
     * Returns the content URI based on the specified media and whether it's internal or external
     * storage.
     *
     * @param media    The RingtoneManager media type.
     * @param internal Whether it's for internal or external storage.
     * @return The media content URI.
     */
    private static Uri getContentUriForMedia(@MediaType int media, boolean internal) {
        switch (media) {
            case Ringtone.MEDIA_VIBRATION:
                return MediaStore.Files.getContentUri(
                        internal ? MediaStore.VOLUME_INTERNAL : MediaStore.VOLUME_EXTERNAL);
            case Ringtone.MEDIA_SOUND:
                return internal ? MediaStore.Audio.Media.INTERNAL_CONTENT_URI
                        : MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
            default:
                throw new IllegalArgumentException("Unsupported media type " + media);
        }
    }

    /**
     * Constructs a where clause based on the media type. This will be used to find all matching
     * sound or vibration files.
     *
     * @param media   The RingtoneManager media type.
     * @param columns The columns that must be true, when media type is {@link Ringtone#MEDIA_SOUND}
     * @return The where clause.
     */
    private static String getWhereClauseForMedia(@MediaType int media, List<String> columns) {
        // TODO(b/296213309): Filtering by ringtone-type isn't supported yet for vibrations.
        if (media == Ringtone.MEDIA_VIBRATION) {
            return TextUtils.formatSimple("(%s='%s')", MediaStore.Files.FileColumns.MIME_TYPE,
                    VibrationXmlParser.APPLICATION_VIBRATION_XML_MIME_TYPE);
        }

        return constructBooleanTrueWhereClause(columns);
    }
    
    /**
     * Constructs a where clause that consists of at least one column being 1
     * (true). This is used to find all matching sounds for the given sound
@@ -867,6 +769,14 @@ public class RingtoneManager {
        return sb.toString();
    }
    
    private Cursor query(Uri uri,
            String[] projection,
            String selection,
            String[] selectionArgs,
            String sortOrder) {
        return query(uri, projection, selection, selectionArgs, sortOrder, mContext);
    }

    private Cursor query(Uri uri,
            String[] projection,
            String selection,

media/tests/ringtone/Android.bp

deleted100644 → 0
+0 −30
Original line number Diff line number Diff line
package {
    // See: http://go/android-license-faq
    default_applicable_licenses: ["frameworks_base_license"],
}

android_test {
    name: "MediaRingtoneTests",

    srcs: ["src/**/*.java"],

    libs: [
        "android.test.runner",
        "android.test.base",
    ],

    static_libs: [
        "androidx.test.rules",
        "testng",
        "androidx.test.ext.truth",
        "frameworks-base-testutils",
    ],

    test_suites: [
        "device-tests",
        "automotive-tests",
    ],

    platform_apis: true,
    certificate: "platform",
}
+0 −41
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2023 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.
-->

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.android.framework.base.media.ringtone.tests">

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.MANAGE_USERS" />

    <application android:debuggable="true">
        <uses-library android:name="android.test.runner" />

        <activity android:name="MediaRingtoneTests"
                  android:label="Media Ringtone Tests"
                  android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>

    </application>

    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
                     android:targetPackage="com.android.framework.base.media.ringtone.tests"
                     android:label="Media Ringtone Tests"/>
</manifest>

media/tests/ringtone/TEST_MAPPING

deleted100644 → 0
+0 −20
Original line number Diff line number Diff line
{
  "presubmit": [
    {
      "name": "MediaRingtoneTests",
      "options": [
        {"exclude-annotation": "androidx.test.filters.LargeTest"},
        {"exclude-annotation": "androidx.test.filters.FlakyTest"},
        {"exclude-annotation": "org.junit.Ignore"}
      ]
    }
  ],
  "postsubmit": [
    {
      "name": "MediaRingtoneTests",
      "options": [
        {"exclude-annotation": "org.junit.Ignore"}
      ]
    }
  ]
}
 No newline at end of file
Loading