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

Commit e25c2082 authored by Chaohui Wang's avatar Chaohui Wang Committed by Android (Google) Code Review
Browse files

Merge "Migrate SearchFeatureProviderImpl to Kotlin" into main

parents 48576381 75a382fc
Loading
Loading
Loading
Loading
+0 −81
Original line number Diff line number Diff line
/*
 * 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.
 *
 */

package com.android.settings.search;

import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.provider.Settings;
import android.text.TextUtils;

import androidx.annotation.NonNull;

import com.android.settingslib.search.SearchIndexableResources;
import com.android.settingslib.search.SearchIndexableResourcesMobile;

/**
 * FeatureProvider for the refactored search code.
 */
public class SearchFeatureProviderImpl implements SearchFeatureProvider {

    private SearchIndexableResources mSearchIndexableResources;

    @Override
    public void verifyLaunchSearchResultPageCaller(@NonNull Context context,
            @NonNull String callerPackage) {
        if (TextUtils.isEmpty(callerPackage)) {
            throw new IllegalArgumentException("ExternalSettingsTrampoline intents "
                    + "must be called with startActivityForResult");
        }
        final boolean isSettingsPackage = TextUtils.equals(callerPackage, context.getPackageName())
                || TextUtils.equals(getSettingsIntelligencePkgName(context), callerPackage);
        final boolean isAllowlistedPackage = isSignatureAllowlisted(context, callerPackage);
        if (isSettingsPackage || isAllowlistedPackage) {
            return;
        }
        throw new SecurityException("Search result intents must be called with from an "
                + "allowlisted package.");
    }

    @Override
    public SearchIndexableResources getSearchIndexableResources() {
        if (mSearchIndexableResources == null) {
            mSearchIndexableResources = new SearchIndexableResourcesMobile();
        }
        return mSearchIndexableResources;
    }

    @Override
    public Intent buildSearchIntent(Context context, int pageId) {
        return new Intent(Settings.ACTION_APP_SEARCH_SETTINGS)
                .setPackage(getSettingsIntelligencePkgName(context))
                .putExtra(Intent.EXTRA_REFERRER, buildReferrer(context, pageId));
    }

    protected boolean isSignatureAllowlisted(Context context, String callerPackage) {
        return false;
    }

    private static Uri buildReferrer(Context context, int pageId) {
        return new Uri.Builder()
                .scheme("android-app")
                .authority(context.getPackageName())
                .path(String.valueOf(pageId))
                .build();
    }
}
+64 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 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.
 *
 */

package com.android.settings.search

import android.content.Context
import android.content.Intent
import android.net.Uri
import android.provider.Settings
import com.android.settings.search.SearchIndexableResourcesFactory.createSearchIndexableResources
import com.android.settingslib.search.SearchIndexableResources

/** FeatureProvider for the refactored search code. */
open class SearchFeatureProviderImpl : SearchFeatureProvider {
    private val lazySearchIndexableResources by lazy { createSearchIndexableResources() }

    override fun verifyLaunchSearchResultPageCaller(context: Context, callerPackage: String) {
        require(callerPackage.isNotEmpty()) {
            "ExternalSettingsTrampoline intents must be called with startActivityForResult"
        }
        val isSettingsPackage = callerPackage == context.packageName
        if (isSettingsPackage ||
            callerPackage == getSettingsIntelligencePkgName(context) ||
            isSignatureAllowlisted(context, callerPackage)) {
            return
        }
        throw SecurityException(
            "Search result intents must be called with from an allowlisted package.")
    }

    override fun getSearchIndexableResources(): SearchIndexableResources =
        lazySearchIndexableResources

    override fun buildSearchIntent(context: Context, pageId: Int): Intent =
        Intent(Settings.ACTION_APP_SEARCH_SETTINGS)
            .setPackage(getSettingsIntelligencePkgName(context))
            .putExtra(Intent.EXTRA_REFERRER, buildReferrer(context, pageId))

    protected open fun isSignatureAllowlisted(context: Context, callerPackage: String): Boolean =
        false

    companion object {
        private fun buildReferrer(context: Context, pageId: Int): Uri =
            Uri.Builder()
                .scheme("android-app")
                .authority(context.packageName)
                .path(pageId.toString())
                .build()
    }
}
+34 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 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.
 */

package com.android.settings.search;

import androidx.annotation.NonNull;

import com.android.settingslib.search.SearchIndexableResources;
import com.android.settingslib.search.SearchIndexableResourcesMobile;

/**
 * Creates the {@link SearchIndexableResourcesMobile}.
 * <p>
 * Since this class is generated by annotation processor, so it can only be created in Java now.
 */
class SearchIndexableResourcesFactory {
    @NonNull
    static SearchIndexableResources createSearchIndexableResources() {
        return new SearchIndexableResourcesMobile();
    }
}
+2 −2
Original line number Diff line number Diff line
@@ -124,8 +124,8 @@ public class SearchFeatureProviderImplTest {
    }

    @Test(expected = IllegalArgumentException.class)
    public void verifyLaunchSearchResultPageCaller_nullCaller_shouldCrash() {
        mProvider.verifyLaunchSearchResultPageCaller(mActivity, null /* caller */);
    public void verifyLaunchSearchResultPageCaller_emptyCaller_shouldCrash() {
        mProvider.verifyLaunchSearchResultPageCaller(mActivity, "");
    }

    @Test(expected = SecurityException.class)