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

Commit 537f0b81 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Build slice from indexed data in SliceProvider"

parents 533dfdfb 8c96843f
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import android.widget.Toolbar;

import com.android.settings.core.FeatureFlags;
import com.android.settings.dashboard.SiteMapManager;
import com.android.settings.overlay.FeatureFactory;

import java.util.List;
import java.util.concurrent.ExecutorService;
@@ -185,6 +186,9 @@ public interface SearchFeatureProvider {
            } else {
                intent = new Intent(activity, SearchActivity.class);
            }
            FeatureFactory.getFactory(
                    activity.getApplicationContext()).getSlicesFeatureProvider()
                    .indexSliceDataAsync(activity.getApplicationContext());
            activity.startActivityForResult(intent, 0 /* requestCode */);
        });
    }
+21 −1
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import android.content.Intent;
import android.graphics.drawable.Icon;
import android.net.Uri;
import android.net.wifi.WifiManager;
import android.support.annotation.VisibleForTesting;

import com.android.settings.R;

@@ -32,13 +33,25 @@ import androidx.app.slice.SliceProvider;
import androidx.app.slice.builders.ListBuilder;

public class SettingsSliceProvider extends SliceProvider {

    private static final String TAG = "SettingsSliceProvider";

    public static final String SLICE_AUTHORITY = "com.android.settings.slices";

    public static final String PATH_WIFI = "wifi";
    public static final String ACTION_WIFI_CHANGED =
            "com.android.settings.slice.action.WIFI_CHANGED";

    public static final String ACTION_TOGGLE_CHANGED =
            "com.android.settings.slice.action.TOGGLE_CHANGED";

    public static final String EXTRA_SLICE_KEY = "com.android.settings.slice.extra.key";

    // TODO -- Associate slice URI with search result instead of separate hardcoded thing

    @VisibleForTesting
    SlicesDatabaseAccessor mSlicesDatabaseAccessor;

    public static Uri getUri(String path) {
        return new Uri.Builder()
                .scheme(ContentResolver.SCHEME_CONTENT)
@@ -48,19 +61,26 @@ public class SettingsSliceProvider extends SliceProvider {

    @Override
    public boolean onCreateSliceProvider() {
        mSlicesDatabaseAccessor = new SlicesDatabaseAccessor(getContext());
        return true;
    }

    @Override
    public Slice onBindSlice(Uri sliceUri) {
        String path = sliceUri.getPath();
        // If adding a new Slice, do not directly match Slice URIs.
        // Use {@link SlicesDatabaseAccessor}.
        switch (path) {
            case "/" + PATH_WIFI:
                return createWifiSlice(sliceUri);
        }
        throw new IllegalArgumentException("Unrecognized slice uri: " + sliceUri);

        return getHoldingSlice(sliceUri);
    }

    private Slice getHoldingSlice(Uri uri) {
        return new ListBuilder(uri).build();
    }

    // TODO (b/70622039) remove this when the proper wifi slice is enabled.
    private Slice createWifiSlice(Uri sliceUri) {
+44 −3
Original line number Diff line number Diff line
@@ -16,7 +16,9 @@

package com.android.settings.slices;

import static com.android.settings.slices.SettingsSliceProvider.ACTION_TOGGLE_CHANGED;
import static com.android.settings.slices.SettingsSliceProvider.ACTION_WIFI_CHANGED;
import static com.android.settings.slices.SettingsSliceProvider.EXTRA_SLICE_KEY;

import android.app.slice.Slice;
import android.content.BroadcastReceiver;
@@ -25,19 +27,34 @@ import android.content.Intent;
import android.net.Uri;
import android.net.wifi.WifiManager;
import android.os.Handler;
import android.text.TextUtils;

import com.android.settings.core.BasePreferenceController;
import com.android.settings.core.TogglePreferenceController;

/**
 * Responds to actions performed on slices and notifies slices of updates in state changes.
 */
public class SliceBroadcastReceiver extends BroadcastReceiver {

    private static String TAG = "SettSliceBroadcastRec";

    /**
     * TODO (b/) move wifi action into generalized case.
     */
    @Override
    public void onReceive(Context context, Intent i) {
        String action = i.getAction();
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        String key = intent.getStringExtra(EXTRA_SLICE_KEY);

        switch (action) {
            case ACTION_TOGGLE_CHANGED:
                handleToggleAction(context, key);
                break;
            case ACTION_WIFI_CHANGED:
                WifiManager wm = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
                boolean newState = i.getBooleanExtra(Slice.EXTRA_TOGGLE_STATE, wm.isWifiEnabled());
                boolean newState = intent.getBooleanExtra(Slice.EXTRA_TOGGLE_STATE,
                        wm.isWifiEnabled());
                wm.setWifiEnabled(newState);
                // Wait a bit for wifi to update (TODO: is there a better way to do this?)
                Handler h = new Handler();
@@ -48,4 +65,28 @@ public class SliceBroadcastReceiver extends BroadcastReceiver {
                break;
        }
    }

    private void handleToggleAction(Context context, String key) {
        if (TextUtils.isEmpty(key)) {
            throw new IllegalStateException("No key passed to Intent for toggle controller");
        }

        BasePreferenceController controller = getBasePreferenceController(context, key);

        if (!(controller instanceof TogglePreferenceController)) {
            throw new IllegalStateException("Toggle action passed for a non-toggle key: " + key);
        }

        // TODO post context.getContentResolver().notifyChanged(uri, null) in the Toggle controller
        // so that it's automatically broadcast to any slice.
        TogglePreferenceController toggleController = (TogglePreferenceController) controller;
        boolean currentValue = toggleController.isChecked();
        toggleController.setChecked(!currentValue);
    }

    private BasePreferenceController getBasePreferenceController(Context context, String key) {
        final SlicesDatabaseAccessor accessor = new SlicesDatabaseAccessor(context);
        final SliceData sliceData = accessor.getSliceDataFromKey(key);
        return SliceBuilderUtils.getPreferenceController(context, sliceData);
    }
}
+125 −0
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.slices;

import static com.android.settings.slices.SettingsSliceProvider.EXTRA_SLICE_KEY;

import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Icon;
import android.text.TextUtils;

import com.android.settings.SubSettings;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.core.TogglePreferenceController;
import com.android.settings.search.DatabaseIndexingUtils;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

import androidx.app.slice.Slice;
import androidx.app.slice.builders.ListBuilder;
import androidx.app.slice.builders.ListBuilder.RowBuilder;

/**
 * Utility class to build Slices objects and Preference Controllers based on the Database managed
 * by {@link SlicesDatabaseHelper}
 */
public class SliceBuilderUtils {

    private static final String TAG = "SliceBuilder";

    /**
     * Build a Slice from {@link SliceData}.
     *
     * @return a {@link Slice} based on the data provided by {@param sliceData}.
     * Will build an {@link Intent} based Slice unless the Preference Controller name in
     * {@param sliceData} is an inline controller.
     */
    public static Slice buildSlice(Context context, SliceData sliceData) {
        final PendingIntent contentIntent = getContentIntent(context, sliceData);
        final Icon icon = Icon.createWithResource(context, sliceData.getIconResource());
        String summaryText = sliceData.getSummary();
        String subtitleText = TextUtils.isEmpty(summaryText)
                ? sliceData.getScreenTitle()
                : summaryText;

        RowBuilder builder = new RowBuilder(sliceData.getUri())
                .setTitle(sliceData.getTitle())
                .setTitleItem(icon)
                .setSubtitle(subtitleText)
                .setContentIntent(contentIntent);

        BasePreferenceController controller = getPreferenceController(context, sliceData);

        // TODO (b/71640747) Respect setting availability.
        // TODO (b/71640678) Add dynamic summary text.

        if (controller instanceof TogglePreferenceController) {
            addToggleAction(context, builder, ((TogglePreferenceController) controller).isChecked(),
                    sliceData.getKey());
        }

        return new ListBuilder(sliceData.getUri())
                .addRow(builder)
                .build();
    }

    /**
     * Looks at the {@link SliceData#preferenceController} from {@param sliceData} and attempts to
     * build a {@link BasePreferenceController}.
     */
    public static BasePreferenceController getPreferenceController(Context context,
            SliceData sliceData) {
        // TODO check for context-only controller first.
        try {
            Class<?> clazz = Class.forName(sliceData.getPreferenceController());
            Constructor<?> preferenceConstructor = clazz.getConstructor(Context.class,
                    String.class);
            return (BasePreferenceController) preferenceConstructor.newInstance(
                    new Object[]{context, sliceData.getKey()});
        } catch (ClassNotFoundException | NoSuchMethodException | InstantiationException |
                IllegalArgumentException | InvocationTargetException | IllegalAccessException e) {
            throw new IllegalStateException(
                    "Invalid preference controller: " + sliceData.getPreferenceController());
        }
    }

    private static void addToggleAction(Context context, RowBuilder builder, boolean isChecked,
            String key) {
        PendingIntent actionIntent = getActionIntent(context,
                SettingsSliceProvider.ACTION_TOGGLE_CHANGED, key);
        builder.addToggle(actionIntent, isChecked);
    }

    private static PendingIntent getActionIntent(Context context, String action, String key) {
        Intent intent = new Intent(action);
        intent.setClass(context, SliceBroadcastReceiver.class);
        intent.putExtra(EXTRA_SLICE_KEY, key);
        return PendingIntent.getBroadcast(context, 0 /* requestCode */, intent,
                PendingIntent.FLAG_CANCEL_CURRENT);
    }

    private static PendingIntent getContentIntent(Context context, SliceData sliceData) {
        Intent intent = DatabaseIndexingUtils.buildSearchResultPageIntent(context,
                sliceData.getFragmentClassName(), sliceData.getKey(), sliceData.getScreenTitle(),
                0 /* TODO */);
        intent.setClassName("com.android.settings", SubSettings.class.getName());
        return PendingIntent.getActivity(context, 0 /* requestCode */, intent, 0 /* flags */);
    }
}
 No newline at end of file
+0 −2
Original line number Diff line number Diff line
@@ -18,7 +18,6 @@ package com.android.settings.slices;

import android.net.Uri;
import android.text.TextUtils;

/**
 * Data class representing a slice stored by {@link SlicesIndexer}.
 * Note that {@link #key} is treated as a primary key for this class and determines equality.
@@ -179,5 +178,4 @@ public class SliceData {
            return mKey;
        }
    }

}
 No newline at end of file
Loading