public class

SliceProviderWrapperContainer

extends java.lang.Object

 java.lang.Object

↳androidx.slice.compat.SliceProviderWrapperContainer

Gradle dependencies

compile group: 'androidx.slice', name: 'slice-core', version: '1.1.0-alpha02'

  • groupId: androidx.slice
  • artifactId: slice-core
  • version: 1.1.0-alpha02

Artifact androidx.slice:slice-core:1.1.0-alpha02 it located at Google repository (https://maven.google.com/)

Androidx artifact mapping:

androidx.slice:slice-core com.android.support:slices-core

Summary

Methods
from java.lang.Objectclone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

Source

/*
 * Copyright 2018 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 androidx.slice.compat;

import static androidx.slice.SliceConvert.wrap;

import android.app.PendingIntent;
import android.app.slice.Slice;
import android.app.slice.SliceManager;
import android.app.slice.SliceProvider;
import android.app.slice.SliceSpec;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ProviderInfo;
import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.annotation.RestrictTo;
import androidx.slice.SliceConvert;

import java.util.Collection;
import java.util.Set;

/**
 * @hide
 */
@RestrictTo(RestrictTo.Scope.LIBRARY)
public class SliceProviderWrapperContainer {

    /**
     */
    @RequiresApi(28)
    public static class SliceProviderWrapper extends SliceProvider {
        private static final String TAG = "SliceProviderWrapper";
        private static final String METHOD_BIND = "bind_slice";
        private static final String METHOD_MAP = "map_slice";
        private static final String EXTRA_URI = "slice_uri";
        private static final String EXTRA_INTENT = "slice_intent";

        private androidx.slice.SliceProvider mSliceProvider;

        private String[] mAutoGrantPermissions;
        private SliceManager mSliceManager;

        public SliceProviderWrapper(androidx.slice.SliceProvider provider,
                String[] autoGrantPermissions) {
            super(autoGrantPermissions);
            mAutoGrantPermissions = autoGrantPermissions == null
                    || autoGrantPermissions.length == 0 ? null : autoGrantPermissions;
            mSliceProvider = provider;
        }

        @Override
        public void attachInfo(Context context, ProviderInfo info) {
            mSliceProvider.attachInfo(context, info);
            super.attachInfo(context, info);
            mSliceManager = context.getSystemService(SliceManager.class);
        }

        @Override
        public boolean onCreate() {
            return true;
        }

        @Override
        public PendingIntent onCreatePermissionRequest(Uri sliceUri) {
            if (mAutoGrantPermissions != null) {
                checkPermissions(sliceUri);
            }
            PendingIntent action = mSliceProvider.onCreatePermissionRequest(
                    sliceUri, getCallingPackage());
            if (action != null) {
                return action;
            }
            return super.onCreatePermissionRequest(sliceUri);
        }

        @Override
        public Bundle call(String method, String arg, Bundle extras) {
            if (mAutoGrantPermissions != null) {
                Uri uri = null;
                if (METHOD_BIND.equals(method)) {
                    uri = extras != null ? (Uri) extras.getParcelable(EXTRA_URI) : null;
                } else if (METHOD_MAP.equals(method)) {
                    Intent intent = extras.getParcelable(EXTRA_INTENT);
                    if (intent != null) {
                        uri = onMapIntentToUri(intent);
                    }
                }
                if (uri != null) {
                    if (mSliceManager.checkSlicePermission(uri, Binder.getCallingPid(),
                                Binder.getCallingUid()) != PackageManager.PERMISSION_GRANTED) {
                        checkPermissions(uri);
                    }
                }
            }
            // Since calls get routed through here on API 28+, need to delegate to
            // SliceProviderWithCallback if the method is remote callback.
            // Note that we use string instead of constant to prevent unnecessary dependency.
            if ("androidx.remotecallback.method.PROVIDER_CALLBACK".equals(method)) {
                return mSliceProvider.call(method, arg, extras);
            }
            return super.call(method, arg, extras);
        }

        private void checkPermissions(Uri uri) {
            if (uri != null) {
                for (String pkg : mAutoGrantPermissions) {
                    if (getContext().checkCallingPermission(pkg)
                            == PackageManager.PERMISSION_GRANTED) {
                        mSliceManager.grantSlicePermission(pkg, uri);
                        getContext().getContentResolver().notifyChange(uri, null);
                        return;
                    }
                }
            }
        }

        @Override
        public Slice onBindSlice(Uri sliceUri, Set<SliceSpec> supportedVersions) {
            androidx.slice.SliceProvider.setSpecs(wrap(supportedVersions));
            try {
                return SliceConvert.unwrap(mSliceProvider.onBindSlice(sliceUri));
            } catch (Exception e) {
                Log.wtf(TAG, "Slice with URI " + sliceUri.toString() + " is invalid.", e);
                return null;
            } finally {
                androidx.slice.SliceProvider.setSpecs(null);
            }
        }

        @Override
        public void onSlicePinned(Uri sliceUri) {
            mSliceProvider.onSlicePinned(sliceUri);
            mSliceProvider.handleSlicePinned(sliceUri);
        }

        @Override
        public void onSliceUnpinned(Uri sliceUri) {
            mSliceProvider.onSliceUnpinned(sliceUri);
            mSliceProvider.handleSliceUnpinned(sliceUri);
        }

        @Override
        public Collection<Uri> onGetSliceDescendants(Uri uri) {
            return mSliceProvider.onGetSliceDescendants(uri);
        }

        /**
         * Maps intents to uris.
         */
        @Override
        public @NonNull Uri onMapIntentToUri(Intent intent) {
            return mSliceProvider.onMapIntentToUri(intent);
        }
    }

    private SliceProviderWrapperContainer() {
    }
}