blob: c3610d93e1933ec5ebffd9bed6dbd682da0d280b [file] [log] [blame]
/*
* Copyright (C) 2016 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.systemui.qs.customize;
import android.Manifest.permission;
import android.app.ActivityManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.Looper;
import android.service.quicksettings.TileService;
import com.android.systemui.R;
import com.android.systemui.qs.QSTile;
import com.android.systemui.qs.QSTile.DrawableIcon;
import com.android.systemui.qs.external.CustomTile;
import com.android.systemui.statusbar.phone.QSTileHost;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
public class TileQueryHelper {
private static final String TAG = "TileQueryHelper";
private final ArrayList<TileInfo> mTiles = new ArrayList<>();
private final ArrayList<String> mSpecs = new ArrayList<>();
private final Context mContext;
private TileStateListener mListener;
public TileQueryHelper(Context context, QSTileHost host) {
mContext = context;
addSystemTiles(host);
// TODO: Live?
}
private void addSystemTiles(QSTileHost host) {
boolean hasColorMod = host.getNightModeController().isEnabled();
String possible = mContext.getString(R.string.quick_settings_tiles_default)
+ ",hotspot,inversion,saver,work,cast" + (hasColorMod ? ",night" : "");
String[] possibleTiles = possible.split(",");
final Handler qsHandler = new Handler(host.getLooper());
final Handler mainHandler = new Handler(Looper.getMainLooper());
for (int i = 0; i < possibleTiles.length; i++) {
final String spec = possibleTiles[i];
final QSTile<?> tile = host.createTile(spec);
if (tile == null || !tile.isAvailable()) {
continue;
}
tile.setListening(true);
tile.clearState();
tile.refreshState();
tile.setListening(false);
qsHandler.post(new Runnable() {
@Override
public void run() {
final QSTile.State state = tile.newTileState();
tile.getState().copyTo(state);
mainHandler.post(new Runnable() {
@Override
public void run() {
addTile(spec, state);
mListener.onTilesChanged(mTiles);
}
});
}
});
}
qsHandler.post(new Runnable() {
@Override
public void run() {
new QueryTilesTask().execute();
}
});
}
public void setListener(TileStateListener listener) {
mListener = listener;
}
private void addTile(String spec, QSTile.State state) {
if (mSpecs.contains(spec)) {
return;
}
TileInfo info = new TileInfo();
info.state = state;
info.spec = spec;
mTiles.add(info);
mSpecs.add(spec);
}
private void addTile(String spec, Drawable drawable, CharSequence label, Context context) {
QSTile.State state = new QSTile.State();
state.label = label;
state.contentDescription = label;
state.icon = new DrawableIcon(drawable);
addTile(spec, state);
}
public static class TileInfo {
public String spec;
public QSTile.State state;
}
private class QueryTilesTask extends AsyncTask<Void, Void, Collection<TileInfo>> {
@Override
protected Collection<TileInfo> doInBackground(Void... params) {
List<TileInfo> tiles = new ArrayList<>();
PackageManager pm = mContext.getPackageManager();
List<ResolveInfo> services = pm.queryIntentServicesAsUser(
new Intent(TileService.ACTION_QS_TILE), 0, ActivityManager.getCurrentUser());
for (ResolveInfo info : services) {
String packageName = info.serviceInfo.packageName;
ComponentName componentName = new ComponentName(packageName, info.serviceInfo.name);
String spec = CustomTile.toSpec(componentName);
Drawable icon = info.serviceInfo.loadIcon(pm);
if (!permission.BIND_QUICK_SETTINGS_TILE.equals(info.serviceInfo.permission)) {
continue;
}
if (icon != null) {
icon.mutate();
icon.setTint(mContext.getColor(android.R.color.white));
}
CharSequence label = info.serviceInfo.loadLabel(pm);
addTile(spec, icon, label != null ? label.toString() : "null", mContext);
}
return tiles;
}
@Override
protected void onPostExecute(Collection<TileInfo> result) {
mTiles.addAll(result);
mListener.onTilesChanged(mTiles);
}
}
public interface TileStateListener {
void onTilesChanged(List<TileInfo> tiles);
}
}