Add slice provider to settings (only provides wifi for now)

- Adds a slice provider to settings that can make a wifi slice

Test: Use SliceBrowser to look at the slice
Bug: 68378569
Change-Id: I8c73ea96a99ee9b0db4a2d7fddc5dbc2b1156da8
This commit is contained in:
Mady Mellor
2017-11-03 09:17:05 -07:00
committed by Jason Monk
parent a6005aa3b1
commit 7c74085df0
4 changed files with 220 additions and 0 deletions

View File

@@ -251,6 +251,8 @@
android:value="com.android.settings.wifi.WifiSettings" /> android:value="com.android.settings.wifi.WifiSettings" />
<meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED" <meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"
android:value="true" /> android:value="true" />
<meta-data android:name="android.metadata.SLICE_URI"
android:value="content://com.android.settings.slices/wifi" />
</activity> </activity>
<!-- Keep compatibility with old shortcuts. --> <!-- Keep compatibility with old shortcuts. -->
@@ -3283,6 +3285,18 @@
</intent-filter> </intent-filter>
</activity> </activity>
<provider android:name=".SettingsSliceProvider"
android:authorities="com.android.settings.slices"
android:exported="true">
</provider>
<receiver
android:name=".SliceBroadcastReceiver" >
<intent-filter>
<action android:name="com.android.settings.slice.action.WIFI_CHANGED"/>
</intent-filter>
</receiver>
<!-- This is the longest AndroidManifest.xml ever. --> <!-- This is the longest AndroidManifest.xml ever. -->
</application> </application>
</manifest> </manifest>

View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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.
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?android:attr/listPreferredItemHeight"
android:paddingTop="16dp"
android:paddingBottom="16dp"
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
android:background="?android:attr/selectableItemBackground"
android:clipToPadding="false">
<include layout="@layout/search_icon_view"/>
<android.app.slice.widget.SliceView
android:id="@android:id/content"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>

View File

@@ -0,0 +1,121 @@
/*
* 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;
import android.app.PendingIntent;
import android.app.slice.Slice;
import android.app.slice.SliceProvider;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Icon;
import android.net.Uri;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
public class SettingsSliceProvider extends SliceProvider {
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";
// TODO -- Associate slice URI with search result instead of separate hardcoded thing
public static final String[] WIFI_SEARCH_TERMS = {"wi-fi", "wifi", "internet"};
public static Uri getUri(String path) {
return new Uri.Builder()
.scheme(ContentResolver.SCHEME_CONTENT)
.authority(SLICE_AUTHORITY)
.appendPath(path).build();
}
@Override
public boolean onCreate() {
return true;
}
@Override
public Slice onBindSlice(Uri sliceUri) {
String path = sliceUri.getPath();
switch (path) {
case "/" + PATH_WIFI:
return createWifi(sliceUri);
}
throw new IllegalArgumentException("Unrecognized slice uri: " + sliceUri);
}
private Slice createWifi(Uri uri) {
// Get wifi state
String[] toggleHints;
WifiManager wifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE);
int wifiState = wifiManager.getWifiState();
boolean wifiEnabled = false;
String state;
switch (wifiState) {
case WifiManager.WIFI_STATE_DISABLED:
case WifiManager.WIFI_STATE_DISABLING:
state = getContext().getString(R.string.disconnected);
break;
case WifiManager.WIFI_STATE_ENABLED:
case WifiManager.WIFI_STATE_ENABLING:
state = wifiManager.getConnectionInfo().getSSID();
WifiInfo.removeDoubleQuotes(state);
wifiEnabled = true;
break;
case WifiManager.WIFI_STATE_UNKNOWN:
default:
state = ""; // just don't show anything?
break;
}
if (wifiEnabled) {
toggleHints = new String[] {Slice.HINT_TOGGLE, Slice.HINT_SELECTED};
} else {
toggleHints = new String[] {Slice.HINT_TOGGLE};
}
// Construct the slice
Slice.Builder b = new Slice.Builder(uri);
b.addSubSlice(new Slice.Builder(b)
.addAction(getIntent("android.settings.WIFI_SETTINGS"),
new Slice.Builder(b)
.addText(getContext().getString(R.string.wifi_settings), null)
.addText(state, null)
.addIcon(Icon.createWithResource(getContext(),
R.drawable.ic_settings_wireless), null, Slice.HINT_HIDDEN)
.addHints(Slice.HINT_TITLE)
.build())
.addAction(getBroadcastIntent(ACTION_WIFI_CHANGED),
new Slice.Builder(b)
.addHints(toggleHints)
.build())
.build());
return b.build();
}
private PendingIntent getIntent(String action) {
Intent intent = new Intent(action);
PendingIntent pi = PendingIntent.getActivity(getContext(), 0, intent, 0);
return pi;
}
private PendingIntent getBroadcastIntent(String action) {
Intent intent = new Intent(action);
intent.setClass(getContext(), SliceBroadcastReceiver.class);
return PendingIntent.getBroadcast(getContext(), 0, intent,
PendingIntent.FLAG_CANCEL_CURRENT);
}
}

View File

@@ -0,0 +1,51 @@
/*
* 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;
import static com.android.settings.SettingsSliceProvider.ACTION_WIFI_CHANGED;
import android.app.slice.Slice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.net.wifi.WifiManager;
import android.os.Handler;
/**
* Responds to actions performed on slices and notifies slices of updates in state changes.
*/
public class SliceBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent i) {
String action = i.getAction();
switch (action) {
case ACTION_WIFI_CHANGED:
WifiManager wm = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
boolean newState = i.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();
h.postDelayed(() -> {
Uri uri = SettingsSliceProvider.getUri(SettingsSliceProvider.PATH_WIFI);
context.getContentResolver().notifyChange(uri, null);
}, 1000);
break;
}
}
}