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

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

Merge "Use ContentProvider for clockfaces" into ub-launcher3-master

parents 0ab3bc3f 7b59d868
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -18,6 +18,8 @@
<resources>
    <string name="themes_stub_package" translatable="false"/>
    <string name="clocks_stub_package" translatable="false"/>
    <!-- Authority of a provider in System UI that will provide preview info for available clockfaces. -->
    <string name="clocks_provider_authority" translatable="false">com.android.keyguard.clock</string>

    <!--Name of metadata in the main launcher Activity which values contains the authority
        corresponding to a ContentProvider in launcher to provide available grids and
+14 −10
Original line number Diff line number Diff line
@@ -15,7 +15,8 @@
 */
package com.android.customization.model.clock;

import android.graphics.drawable.Drawable;
import android.content.Context;
import android.provider.Settings.Secure;
import android.text.TextUtils;
import android.view.View;
import android.widget.ImageView;
@@ -23,15 +24,16 @@ import android.widget.ImageView;
import com.android.customization.model.CustomizationManager;
import com.android.customization.model.CustomizationOption;
import com.android.wallpaper.R;
import com.android.wallpaper.asset.Asset;

public class Clockface implements CustomizationOption<Clockface> {

    private final String mTitle;
    private final String mId;
    private final Drawable mPreview;
    private final Drawable mThumbnail;
    private final Asset mPreview;
    private final Asset mThumbnail;

    private Clockface(String title, String id, Drawable preview, Drawable thumbnail) {
    private Clockface(String title, String id, Asset preview, Asset thumbnail) {
        mTitle = title;
        mId = id;
        mPreview = preview;
@@ -45,7 +47,9 @@ public class Clockface implements CustomizationOption<Clockface> {

    @Override
    public void bindThumbnailTile(View view) {
        ((ImageView) view.findViewById(R.id.clock_option_thumbnail)).setImageDrawable(mThumbnail);
        ImageView thumbView = view.findViewById(R.id.clock_option_thumbnail);
        mThumbnail.loadDrawableWithTransition(thumbView.getContext(), thumbView, 50, null,
                thumbView.getResources().getColor(android.R.color.transparent, null));
    }

    @Override
@@ -61,7 +65,7 @@ public class Clockface implements CustomizationOption<Clockface> {
        return R.layout.clock_option;
    }

    public Drawable getPreviewDrawable() {
    public Asset getPreviewAsset() {
        return mPreview;
    }

@@ -72,8 +76,8 @@ public class Clockface implements CustomizationOption<Clockface> {
    public static class Builder {
        private String mTitle;
        private String mId;
        private Drawable mPreview;
        private Drawable mThumbnail;
        private Asset mPreview;
        private Asset mThumbnail;

        public Clockface build() {
            return new Clockface(mTitle, mId, mPreview, mThumbnail);
@@ -89,12 +93,12 @@ public class Clockface implements CustomizationOption<Clockface> {
            return this;
        }

        public Builder setPreview(Drawable preview) {
        public Builder setPreview(Asset preview) {
            mPreview = preview;
            return this;
        }

        public Builder setThumbnail(Drawable thumbnail) {
        public Builder setThumbnail(Asset thumbnail) {
            mThumbnail = thumbnail;
            return this;
        }
+130 −0
Original line number Diff line number Diff line
package com.android.customization.model.clock;

import android.content.ContentResolver;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.pm.ProviderInfo;
import android.database.Cursor;
import android.net.Uri;
import android.os.AsyncTask;
import android.text.TextUtils;

import com.android.customization.model.CustomizationManager.OptionsFetchedListener;
import com.android.customization.model.clock.Clockface.Builder;
import com.android.wallpaper.R;
import com.android.wallpaper.asset.ContentUriAsset;

import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions;

import java.util.ArrayList;
import java.util.List;

public class ContentProviderClockProvider implements ClockProvider {

    private final Context mContext;
    private final ProviderInfo mProviderInfo;
    private List<Clockface> mClocks;

    public ContentProviderClockProvider(Context context) {
        mContext = context;
        String providerAuthority = mContext.getString(R.string.clocks_provider_authority);
        // TODO: check permissions if needed
        mProviderInfo = TextUtils.isEmpty(providerAuthority) ? null
                : mContext.getPackageManager().resolveContentProvider(providerAuthority,
                        PackageManager.MATCH_SYSTEM_ONLY);
    }

    @Override
    public boolean isAvailable() {
        return mProviderInfo != null;
    }

    @Override
    public void fetch(OptionsFetchedListener<Clockface> callback, boolean reload) {
        if (!isAvailable()) {
            if (callback != null) {
                callback.onOptionsLoaded(null);
            }
            return;
        }
        if (mClocks != null && !reload) {
            if (callback != null) {
                callback.onOptionsLoaded(mClocks);
            }
            return;
        }
        new ClocksFetchTask(mContext, mProviderInfo, options -> {
            mClocks = options;
            if (callback != null) {
                callback.onOptionsLoaded(mClocks);
            }
        }).execute();
    }

    private static class ClocksFetchTask extends AsyncTask<Void, Void, List<Clockface>> {

        private static final String LIST_OPTIONS = "list_options";

        private static final String COL_NAME = "name";
        private static final String COL_TITLE = "title";
        private static final String COL_ID = "id";
        private static final String COL_THUMBNAIL = "thumbnail";
        private static final String COL_PREVIEW = "preview";

        private final OptionsFetchedListener<Clockface> mCallback;
        private Context mContext;
        private final ProviderInfo mProviderInfo;

        public ClocksFetchTask(Context context, ProviderInfo providerInfo,
                OptionsFetchedListener<Clockface> callback) {
            super();
            mContext = context;
            mProviderInfo = providerInfo;
            mCallback = callback;
        }

        @Override
        protected List<Clockface> doInBackground(Void... voids) {
            Uri optionsUri = new Uri.Builder()
                    .scheme(ContentResolver.SCHEME_CONTENT)
                    .authority(mProviderInfo.authority)
                    .appendPath(LIST_OPTIONS)
                    .build();

            ContentResolver resolver = mContext.getContentResolver();

            List<Clockface> clockfaces = new ArrayList<>();
            try (Cursor c = resolver.query(optionsUri, null, null, null, null)) {
                while(c.moveToNext()) {
                    String id = c.getString(c.getColumnIndex(COL_ID));
                    String title = c.getString(c.getColumnIndex(COL_TITLE));
                    String thumbnailUri = c.getString(c.getColumnIndex(COL_THUMBNAIL));
                    String previewUri = c.getString(c.getColumnIndex(COL_PREVIEW));
                    Uri thumbnail = Uri.parse(thumbnailUri);
                    Uri preview = Uri.parse(previewUri);

                    Clockface.Builder builder = new Builder();
                    builder.setId(id).setTitle(title)
                            .setThumbnail(new ContentUriAsset(mContext, thumbnail,
                                    RequestOptions.fitCenterTransform()))
                            .setPreview(new ContentUriAsset(mContext, preview,
                                    RequestOptions.fitCenterTransform()));
                    clockfaces.add(builder.build());
                }
                Glide.get(mContext).clearDiskCache();
            } catch (Exception e) {
                clockfaces = null;
            } finally {
                mContext = null;
            }
            return clockfaces;
        }

        @Override
        protected void onPostExecute(List<Clockface> clockfaces) {
            super.onPostExecute(clockfaces);
            mCallback.onOptionsLoaded(clockfaces);
        }
    }
}
+0 −76
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 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.customization.model.clock;

import android.content.Context;
import android.content.res.Resources.NotFoundException;
import android.util.Log;

import com.android.customization.model.CustomizationManager.OptionsFetchedListener;
import com.android.customization.model.ResourcesApkProvider;
import com.android.customization.model.clock.Clockface.Builder;
import com.android.wallpaper.R;

import java.util.ArrayList;
import java.util.List;

public class ResourcesApkClockProvider extends ResourcesApkProvider implements ClockProvider {

    private static final String TAG = "ResourcesApkClockProvider";

    private static final String CLOCKS_ARRAY = "clocks";
    private static final String TITLE_PREFIX = "clock_title_";
    private static final String ID_PREFIX = "clock_id_";
    private static final String PREVIEW_PREFIX = "clock_preview_";
    private static final String THUMBNAIL_PREFIX = "clock_thumbnail_";

    private List<Clockface> mClocks;

    public ResourcesApkClockProvider(Context context){
        super(context, context.getString(R.string.clocks_stub_package));
    }

    @Override
    public void fetch(OptionsFetchedListener<Clockface> callback, boolean reload) {
        if (mClocks == null || reload) {
            mClocks = new ArrayList<>();
            loadAll();
        }

        if(callback != null) {
            callback.onOptionsLoaded(mClocks);
        }
    }

    private void loadAll() {
        String[] clockNames = getItemsFromStub(CLOCKS_ARRAY);

        for (String clockName : clockNames) {
            try {
                Builder builder = new Builder();

                builder.setTitle(getItemStringFromStub(TITLE_PREFIX, clockName))
                        .setId(getItemStringFromStub(ID_PREFIX, clockName))
                        .setPreview(getItemDrawableFromStub(PREVIEW_PREFIX, clockName))
                        .setThumbnail(getItemDrawableFromStub(THUMBNAIL_PREFIX, clockName));

                mClocks.add(builder.build());
            } catch (NotFoundException e) {
                Log.i(TAG, "Resource not found, skipping clock", e);
            }
        }
    }
}
+3 −2
Original line number Diff line number Diff line
@@ -34,7 +34,7 @@ import com.android.customization.model.CustomizationManager;
import com.android.customization.model.CustomizationOption;
import com.android.customization.model.clock.ClockManager;
import com.android.customization.model.clock.Clockface;
import com.android.customization.model.clock.ResourcesApkClockProvider;
import com.android.customization.model.clock.ContentProviderClockProvider;
import com.android.customization.model.grid.GridOption;
import com.android.customization.model.grid.GridOptionsManager;
import com.android.customization.model.grid.LauncherGridOptionsProvider;
@@ -134,7 +134,8 @@ public class CustomizationPickerActivity extends FragmentActivity implements Wal
            mSections.put(R.id.nav_theme, new ThemeSection(R.id.nav_theme, themeManager));
        }
        //Clock
        ClockManager clockManager = new ClockManager(this, new ResourcesApkClockProvider(this));
        //ClockManager clockManager = new ClockManager(this, new ResourcesApkClockProvider(this));
        ClockManager clockManager = new ClockManager(this, new ContentProviderClockProvider(this));
        if (clockManager.isAvailable()) {
            mSections.put(R.id.nav_clock, new ClockSection(R.id.nav_clock, clockManager));
        }
Loading