Remove PartnerInterface and LiveLockScreen
Change-Id: I8044de599ef6db8e9a1ff63e43dc2cea9c28d02a
This commit is contained in:
@@ -1,226 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2016 The CyanogenMod 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 lineageos.app;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.app.AppGlobals;
|
||||
import android.app.Service;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Binder;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteCallbackList;
|
||||
import android.os.RemoteException;
|
||||
import android.os.UserHandle;
|
||||
import android.util.Log;
|
||||
|
||||
import lineageos.platform.Manifest;
|
||||
|
||||
/**
|
||||
* Base Live lock screen manager service to be extended by applications that implement the
|
||||
* {@link LiveLockScreenManager#SERVICE_INTERFACE}
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
abstract public class BaseLiveLockManagerService extends Service
|
||||
implements ILiveLockScreenManagerProvider {
|
||||
private static final String TAG = BaseLiveLockManagerService.class.getSimpleName();
|
||||
|
||||
private final RemoteCallbackList<ILiveLockScreenChangeListener> mChangeListeners =
|
||||
new RemoteCallbackList<>();
|
||||
|
||||
@Override
|
||||
public final IBinder onBind(Intent intent) {
|
||||
return mService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final IBinder asBinder() {
|
||||
return mService;
|
||||
}
|
||||
|
||||
@Override
|
||||
abstract public void enqueueLiveLockScreen(String pkg, int id, LiveLockScreenInfo lls,
|
||||
int[] idReceived, int userId) throws RemoteException;
|
||||
|
||||
@Override
|
||||
abstract public void cancelLiveLockScreen(String pkg, int id, int userId)
|
||||
throws RemoteException;
|
||||
|
||||
@Override
|
||||
abstract public LiveLockScreenInfo getCurrentLiveLockScreen() throws RemoteException;
|
||||
|
||||
@Override
|
||||
abstract public void updateDefaultLiveLockScreen(LiveLockScreenInfo llsInfo)
|
||||
throws RemoteException;
|
||||
|
||||
@Override
|
||||
public boolean getLiveLockScreenEnabled() throws RemoteException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean registerChangeListener(
|
||||
ILiveLockScreenChangeListener listener) throws RemoteException {
|
||||
return mChangeListeners.register(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean unregisterChangeListener(
|
||||
ILiveLockScreenChangeListener listener) throws RemoteException {
|
||||
return mChangeListeners.unregister(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method should be called whenever there is an update to the current Live lock screen
|
||||
* to be displayed.
|
||||
*
|
||||
* @param llsInfo LiveLockScreenInfo for the current Live lock screen
|
||||
*/
|
||||
protected final void notifyChangeListeners(LiveLockScreenInfo llsInfo) {
|
||||
int N = mChangeListeners.beginBroadcast();
|
||||
for (int i = 0; i < N; i++) {
|
||||
ILiveLockScreenChangeListener listener = mChangeListeners.getBroadcastItem(i);
|
||||
try {
|
||||
listener.onLiveLockScreenChanged(llsInfo);
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, "Unable to notifiy change listener", e);
|
||||
}
|
||||
}
|
||||
mChangeListeners.finishBroadcast();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the caller has been granted the
|
||||
* {@link lineageos.platform.Manifest.permission#LIVE_LOCK_SCREEN_MANAGER_ACCESS_PRIVATE}
|
||||
* permission.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private final boolean hasPrivatePermissions() {
|
||||
return checkCallingPermission(Manifest.permission
|
||||
.LIVE_LOCK_SCREEN_MANAGER_ACCESS_PRIVATE) == PackageManager.PERMISSION_GRANTED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enforces the {@link lineageos.platform.Manifest.permission#LIVE_LOCK_SCREEN_MANAGER_ACCESS}
|
||||
* permission.
|
||||
*/
|
||||
protected final void enforceAccessPermission() {
|
||||
if (hasPrivatePermissions()) return;
|
||||
|
||||
enforceCallingPermission(Manifest.permission.LIVE_LOCK_SCREEN_MANAGER_ACCESS,
|
||||
null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enforces the
|
||||
* {@link lineageos.platform.Manifest.permission#LIVE_LOCK_SCREEN_MANAGER_ACCESS_PRIVATE}
|
||||
* permission.
|
||||
*/
|
||||
protected final void enforcePrivateAccessPermission() {
|
||||
enforceCallingPermission(
|
||||
Manifest.permission.LIVE_LOCK_SCREEN_MANAGER_ACCESS_PRIVATE, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enforces the LLS being shown/canceled is from the calling package or from a system app that
|
||||
* has the
|
||||
* {@link lineageos.platform.Manifest.permission#LIVE_LOCK_SCREEN_MANAGER_ACCESS_PRIVATE}
|
||||
* permission.
|
||||
*
|
||||
* @param pkg Package name of caller
|
||||
* @param llsInfo Live lock screen info with component to check
|
||||
*/
|
||||
protected final void enforceSamePackageOrSystem(String pkg,
|
||||
@NonNull LiveLockScreenInfo llsInfo) {
|
||||
// only apps with the private permission can show/cancel live lock screens from other
|
||||
// packages
|
||||
if (hasPrivatePermissions()) return;
|
||||
|
||||
if (llsInfo.component != null && !llsInfo.component.getPackageName().equals(pkg)) {
|
||||
throw new SecurityException("Modifying Live lock screen from different packages not " +
|
||||
"allowed. Calling package: " + pkg + " LLS package: " +
|
||||
llsInfo.component.getPackageName());
|
||||
}
|
||||
|
||||
final int uid = Binder.getCallingUid();
|
||||
try {
|
||||
ApplicationInfo ai = AppGlobals.getPackageManager().getApplicationInfo(
|
||||
pkg, 0, UserHandle.getCallingUserId());
|
||||
if (ai == null) {
|
||||
throw new SecurityException("Unknown package " + pkg);
|
||||
}
|
||||
if (!UserHandle.isSameApp(ai.uid, uid)) {
|
||||
throw new SecurityException("Calling uid " + uid + " gave package"
|
||||
+ pkg + " which is owned by uid " + ai.uid);
|
||||
}
|
||||
} catch (RemoteException re) {
|
||||
throw new SecurityException("Unknown package " + pkg + "\n" + re);
|
||||
}
|
||||
}
|
||||
|
||||
private final IBinder mService = new ILiveLockScreenManagerProvider.Stub() {
|
||||
@Override
|
||||
public void enqueueLiveLockScreen(String pkg, int id, LiveLockScreenInfo llsInfo,
|
||||
int[] idReceived, int userId) throws RemoteException {
|
||||
enforceAccessPermission();
|
||||
enforceSamePackageOrSystem(pkg, llsInfo);
|
||||
BaseLiveLockManagerService.this.enqueueLiveLockScreen(pkg, id, llsInfo, idReceived,
|
||||
userId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelLiveLockScreen(String pkg, int id, int userId) throws RemoteException {
|
||||
enforceAccessPermission();
|
||||
BaseLiveLockManagerService.this.cancelLiveLockScreen(pkg, id, userId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LiveLockScreenInfo getCurrentLiveLockScreen() throws RemoteException {
|
||||
enforceAccessPermission();
|
||||
return BaseLiveLockManagerService.this.getCurrentLiveLockScreen();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDefaultLiveLockScreen(LiveLockScreenInfo llsInfo) throws RemoteException {
|
||||
enforcePrivateAccessPermission();
|
||||
BaseLiveLockManagerService.this.updateDefaultLiveLockScreen(llsInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getLiveLockScreenEnabled() throws RemoteException {
|
||||
enforceAccessPermission();
|
||||
return BaseLiveLockManagerService.this.getLiveLockScreenEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean registerChangeListener(
|
||||
ILiveLockScreenChangeListener listener) throws RemoteException {
|
||||
enforcePrivateAccessPermission();
|
||||
return BaseLiveLockManagerService.this.registerChangeListener(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean unregisterChangeListener(
|
||||
ILiveLockScreenChangeListener listener) throws RemoteException {
|
||||
enforcePrivateAccessPermission();
|
||||
return BaseLiveLockManagerService.this.unregisterChangeListener(listener);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
/*
|
||||
** Copyright (C) 2016 The CyanogenMod 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 lineageos.app;
|
||||
|
||||
import lineageos.app.LiveLockScreenInfo;
|
||||
|
||||
/**
|
||||
* Listener interface for notifying clients that the current Live lock screen has changed.
|
||||
* @hide
|
||||
*/
|
||||
interface ILiveLockScreenChangeListener {
|
||||
void onLiveLockScreenChanged(in LiveLockScreenInfo llsInfo);
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
/*
|
||||
** Copyright (C) 2016 The CyanogenMod 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 lineageos.app;
|
||||
|
||||
import lineageos.app.ILiveLockScreenChangeListener;
|
||||
import lineageos.app.LiveLockScreenInfo;
|
||||
|
||||
/** @hide */
|
||||
interface ILiveLockScreenManager {
|
||||
|
||||
/**
|
||||
* Enqueue a Live lock screen to be displayed.
|
||||
*/
|
||||
void enqueueLiveLockScreen(String pkg, int id, in LiveLockScreenInfo lls,
|
||||
inout int[] idReceived, int userId);
|
||||
|
||||
/**
|
||||
* Cancel displaying a Live lock screen.
|
||||
*/
|
||||
void cancelLiveLockScreen(String pkg, int id, int userId);
|
||||
|
||||
/**
|
||||
* Get the current Live lock screen that should be displayed.
|
||||
*/
|
||||
LiveLockScreenInfo getCurrentLiveLockScreen();
|
||||
|
||||
/**
|
||||
* Get the default Live lock screen. This is the Live lock screen that should be displayed
|
||||
* when no other Live lock screens are queued.
|
||||
*/
|
||||
LiveLockScreenInfo getDefaultLiveLockScreen();
|
||||
|
||||
/**
|
||||
* Set the default Live lock screen. This is the Live lock screen that should be displayed
|
||||
* when no other Live lock screens are queued.
|
||||
*/
|
||||
void setDefaultLiveLockScreen(in LiveLockScreenInfo llsInfo);
|
||||
|
||||
/**
|
||||
* Set whether Live lock screen feature is enabled.
|
||||
*/
|
||||
oneway void setLiveLockScreenEnabled(boolean enabled);
|
||||
|
||||
/**
|
||||
* Get the enabled state of the Live lock screen feature.
|
||||
*/
|
||||
boolean getLiveLockScreenEnabled();
|
||||
|
||||
/**
|
||||
* Registers an ILiveLockScreenChangeListener that will be called when the current Live lock
|
||||
* screen changes.
|
||||
*/
|
||||
boolean registerChangeListener(in ILiveLockScreenChangeListener listener);
|
||||
|
||||
/**
|
||||
* Unregisters a previously registered ILiveLockScreenChangeListener.
|
||||
*/
|
||||
boolean unregisterChangeListener(in ILiveLockScreenChangeListener listener);
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
/*
|
||||
** Copyright (C) 2016 The CyanogenMod 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 lineageos.app;
|
||||
|
||||
import lineageos.app.ILiveLockScreenChangeListener;
|
||||
import lineageos.app.LiveLockScreenInfo;
|
||||
|
||||
/**
|
||||
* Interface to be implemented by services that support the
|
||||
* {@link LiveLockScreenManager#SERVICE_INTERFACE}
|
||||
* @hide
|
||||
*/
|
||||
interface ILiveLockScreenManagerProvider {
|
||||
|
||||
/**
|
||||
* Enqueue a Live lock screen to be displayed.
|
||||
*/
|
||||
void enqueueLiveLockScreen(String pkg, int id, in LiveLockScreenInfo lls,
|
||||
inout int[] idReceived, int userId);
|
||||
|
||||
/**
|
||||
* Cancel displaying a Live lock screen.
|
||||
*/
|
||||
void cancelLiveLockScreen(String pkg, int id, int userId);
|
||||
|
||||
/**
|
||||
* Get the current Live lock screen that should be displayed.
|
||||
*/
|
||||
LiveLockScreenInfo getCurrentLiveLockScreen();
|
||||
|
||||
/**
|
||||
* Called when the default Live lock screen has changed.
|
||||
*/
|
||||
oneway void updateDefaultLiveLockScreen(in LiveLockScreenInfo llsInfo);
|
||||
|
||||
/**
|
||||
* Get the enabled state of the Live lock screen feature.
|
||||
*/
|
||||
boolean getLiveLockScreenEnabled();
|
||||
|
||||
/**
|
||||
* Registers an ILiveLockScreenChangeListener that will be called when the current Live lock
|
||||
* screen changes.
|
||||
*/
|
||||
boolean registerChangeListener(in ILiveLockScreenChangeListener listener);
|
||||
|
||||
/**
|
||||
* Unregisters a previously registered ILiveLockScreenChangeListener.
|
||||
*/
|
||||
boolean unregisterChangeListener(in ILiveLockScreenChangeListener listener);
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
/* //device/java/android/android/app/IProfileManager.aidl
|
||||
**
|
||||
** Copyright (C) 2015 The CyanogenMod 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 lineageos.app;
|
||||
|
||||
/** {@hide} */
|
||||
interface IPartnerInterface
|
||||
{
|
||||
void setAirplaneModeEnabled(boolean enabled);
|
||||
void setMobileDataEnabled(boolean enabled);
|
||||
boolean setZenMode(int mode);
|
||||
void shutdown();
|
||||
void reboot();
|
||||
String getCurrentHotwordPackageName();
|
||||
boolean setZenModeWithDuration(int mode, long durationMillis);
|
||||
}
|
||||
@@ -53,17 +53,6 @@ public final class LineageContextConstants {
|
||||
*/
|
||||
public static final String LINEAGE_PROFILE_SERVICE = "profile";
|
||||
|
||||
/**
|
||||
* Use with {@link android.content.Context#getSystemService} to retrieve a
|
||||
* {@link lineageos.app.PartnerInterface} interact with system settings.
|
||||
*
|
||||
* @see android.content.Context#getSystemService
|
||||
* @see lineageos.app.PartnerInterface
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final String LINEAGE_PARTNER_INTERFACE = "lineagepartnerinterface";
|
||||
|
||||
/**
|
||||
* Use with {@link android.content.Context#getSystemService} to retrieve a
|
||||
* {@link lineageos.app.LineageTelephonyManager} to manage the phone and
|
||||
@@ -107,11 +96,6 @@ public final class LineageContextConstants {
|
||||
*/
|
||||
public static final String LINEAGE_ICON_CACHE_SERVICE = "lineageiconcache";
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public static final String LINEAGE_LIVE_LOCK_SCREEN_SERVICE = "lineagelivelockscreen";
|
||||
|
||||
/**
|
||||
* Use with {@link android.content.Context#getSystemService} to retrieve a
|
||||
* {@link lineageos.weather.LineageWeatherManager} to manage the weather service
|
||||
@@ -191,22 +175,6 @@ public final class LineageContextConstants {
|
||||
@SdkConstant(SdkConstant.SdkConstantType.FEATURE)
|
||||
public static final String PERFORMANCE = "org.lineageos.performance";
|
||||
|
||||
/**
|
||||
* Feature for {@link PackageManager#getSystemAvailableFeatures} and
|
||||
* {@link PackageManager#hasSystemFeature}: The device includes the lineage partner service
|
||||
* utilized by the lineage sdk.
|
||||
*/
|
||||
@SdkConstant(SdkConstant.SdkConstantType.FEATURE)
|
||||
public static final String PARTNER = "org.lineageos.partner";
|
||||
|
||||
/*
|
||||
* Feature for {@link PackageManager#getSystemAvailableFeatures} and
|
||||
* {@link PackageManager#hasSystemFeature}: The device includes the Live lock screen
|
||||
* feature.
|
||||
*/
|
||||
@SdkConstant(SdkConstant.SdkConstantType.FEATURE)
|
||||
public static final String LIVE_LOCK_SCREEN = "org.lineageos.livelockscreen";
|
||||
|
||||
/**
|
||||
* Feature for {@link PackageManager#getSystemAvailableFeatures} and
|
||||
* {@link PackageManager#hasSystemFeature}: The device includes the lineage weather weather
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2016 The CyanogenMod 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 lineageos.app;
|
||||
|
||||
parcelable LiveLockScreenInfo;
|
||||
@@ -1,189 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2016 The CyanogenMod 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 lineageos.app;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.content.ComponentName;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import lineageos.os.Build;
|
||||
import lineageos.os.Concierge;
|
||||
import lineageos.os.Concierge.ParcelInfo;
|
||||
|
||||
/**
|
||||
* Data structure defining a Live lock screen.
|
||||
*/
|
||||
public class LiveLockScreenInfo implements Parcelable {
|
||||
|
||||
/**
|
||||
* Default Live lock screen {@link #priority}.
|
||||
*/
|
||||
public static final int PRIORITY_DEFAULT = 0;
|
||||
|
||||
/**
|
||||
* Lower {@link #priority}, for items that are less important.
|
||||
*/
|
||||
public static final int PRIORITY_LOW = -1;
|
||||
|
||||
/**
|
||||
* Lowest {@link #priority}.
|
||||
*/
|
||||
public static final int PRIORITY_MIN = -2;
|
||||
|
||||
/**
|
||||
* Higher {@link #priority}, for items that are more important
|
||||
*/
|
||||
public static final int PRIORITY_HIGH = 1;
|
||||
|
||||
/**
|
||||
* Highest {@link #priority}.
|
||||
*/
|
||||
public static final int PRIORITY_MAX = 2;
|
||||
|
||||
/**
|
||||
* The component, which implements
|
||||
* {@link lineageos.externalviews.KeyguardExternalViewProviderService}, to display for this
|
||||
* live lock screen.
|
||||
*/
|
||||
public ComponentName component;
|
||||
|
||||
/**
|
||||
* Relative priority for this Live lock screen.
|
||||
*/
|
||||
public int priority;
|
||||
|
||||
/**
|
||||
* Constructs a LiveLockScreenInfo object with the given values.
|
||||
* You might want to consider using {@link Builder} instead.
|
||||
*/
|
||||
public LiveLockScreenInfo(@NonNull ComponentName component, int priority) {
|
||||
this.component = component;
|
||||
this.priority = priority;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a LiveLockScreenInfo object with default values.
|
||||
* You might want to consider using {@link Builder} instead.
|
||||
*/
|
||||
public LiveLockScreenInfo()
|
||||
{
|
||||
this.component = null;
|
||||
this.priority = PRIORITY_DEFAULT;
|
||||
}
|
||||
|
||||
private LiveLockScreenInfo(Parcel source) {
|
||||
// Read parcelable version via the Concierge
|
||||
ParcelInfo parcelInfo = Concierge.receiveParcel(source);
|
||||
int parcelableVersion = parcelInfo.getParcelVersion();
|
||||
|
||||
this.priority = source.readInt();
|
||||
String component = source.readString();
|
||||
this.component = !TextUtils.isEmpty(component)
|
||||
? ComponentName.unflattenFromString(component)
|
||||
: null;
|
||||
|
||||
// Complete parcel info for the concierge
|
||||
parcelInfo.complete();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
// Tell the concierge to prepare the parcel
|
||||
ParcelInfo parcelInfo = Concierge.prepareParcel(dest);
|
||||
|
||||
dest.writeInt(priority);
|
||||
dest.writeString(component != null ? component.flattenToString() : "");
|
||||
|
||||
// Complete the parcel info for the concierge
|
||||
parcelInfo.complete();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "LiveLockScreenInfo: priority=" + priority +
|
||||
", component=" + component;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LiveLockScreenInfo clone() {
|
||||
LiveLockScreenInfo that = new LiveLockScreenInfo();
|
||||
cloneInto(that);
|
||||
return that;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy all (or if heavy is false, all except Bitmaps and RemoteViews) members
|
||||
* of this into that.
|
||||
* @hide
|
||||
*/
|
||||
public void cloneInto(LiveLockScreenInfo that) {
|
||||
that.component = this.component.clone();
|
||||
that.priority = this.priority;
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<LiveLockScreenInfo> CREATOR =
|
||||
new Parcelable.Creator<LiveLockScreenInfo>() {
|
||||
@Override
|
||||
public LiveLockScreenInfo createFromParcel(Parcel source) {
|
||||
return new LiveLockScreenInfo(source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LiveLockScreenInfo[] newArray(int size) {
|
||||
return new LiveLockScreenInfo[0];
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Builder class for {@link LiveLockScreenInfo} objects. Provides a convenient way to set
|
||||
* various fields of a {@link LiveLockScreenInfo}.
|
||||
*/
|
||||
public static class Builder {
|
||||
private int mPriority;
|
||||
private ComponentName mComponent;
|
||||
|
||||
public Builder setPriority(int priority) {
|
||||
if (priority < PRIORITY_MIN || priority > PRIORITY_MAX) {
|
||||
throw new IllegalArgumentException("Invalid priorty given (" + priority + "): " +
|
||||
PRIORITY_MIN + " <= priority <= " + PRIORITY_MIN);
|
||||
}
|
||||
mPriority = priority;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setComponent(@NonNull ComponentName component) {
|
||||
if (component == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"Cannot call setComponent with a null component");
|
||||
}
|
||||
mComponent = component;
|
||||
return this;
|
||||
}
|
||||
|
||||
public LiveLockScreenInfo build() {
|
||||
return new LiveLockScreenInfo(mComponent, mPriority);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,182 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2016 The CyanogenMod 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 lineageos.app;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.SdkConstant;
|
||||
import android.content.Context;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.os.UserHandle;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* Manages enabling/disabling Live lock screens as well as what Live lock screen to display when
|
||||
* enabled.
|
||||
*/
|
||||
public class LiveLockScreenManager {
|
||||
private static final String TAG = LiveLockScreenManager.class.getSimpleName();
|
||||
private static ILiveLockScreenManager sService;
|
||||
private static LiveLockScreenManager sInstance;
|
||||
|
||||
private Context mContext;
|
||||
|
||||
/**
|
||||
* The {@link android.content.Intent} that must be declared as handled by the service.
|
||||
*/
|
||||
@SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
|
||||
public static final String SERVICE_INTERFACE
|
||||
= "lineageos.app.LiveLockScreenManagerService";
|
||||
|
||||
private LiveLockScreenManager(Context context) {
|
||||
mContext = context;
|
||||
sService = getService();
|
||||
if (context.getPackageManager().hasSystemFeature(
|
||||
LineageContextConstants.Features.LIVE_LOCK_SCREEN) && sService == null) {
|
||||
Log.wtf(TAG, "Unable to get LiveLockScreenManagerService. " +
|
||||
"The service either crashed, was not started, or the interface has " +
|
||||
"been called to early in SystemServer init");
|
||||
}
|
||||
}
|
||||
|
||||
private ILiveLockScreenManager getService() {
|
||||
if (sService == null) {
|
||||
IBinder b = ServiceManager.getService(LineageContextConstants.LINEAGE_LIVE_LOCK_SCREEN_SERVICE);
|
||||
if (b != null) {
|
||||
sService = ILiveLockScreenManager.Stub.asInterface(b);
|
||||
}
|
||||
}
|
||||
|
||||
return sService;
|
||||
}
|
||||
|
||||
private void logServiceException(Exception e) {
|
||||
Log.w(TAG, "Unable to access LiveLockScreenServiceBroker", e);
|
||||
}
|
||||
|
||||
public static LiveLockScreenManager getInstance(Context context) {
|
||||
if (sInstance == null) {
|
||||
sInstance = new LiveLockScreenManager(context);
|
||||
}
|
||||
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests a Live lock screen, defined in {@param lls}, to be displayed with the given id.
|
||||
* @param id An identifier for this notification unique within your application.
|
||||
* @param llsInfo A {@link LiveLockScreenInfo} object describing what Live lock screen to show
|
||||
* the user.
|
||||
* @return True if the Live lock screen was successfully received by the backing service
|
||||
*/
|
||||
public boolean show(int id, @NonNull final LiveLockScreenInfo llsInfo) {
|
||||
int[] idOut = new int[1];
|
||||
String pkg = mContext.getPackageName();
|
||||
boolean success = true;
|
||||
try {
|
||||
sService.enqueueLiveLockScreen(pkg, id, llsInfo, idOut, UserHandle.myUserId());
|
||||
if (id != idOut[0]) {
|
||||
Log.w(TAG, "show: id corrupted: sent " + id + ", got back " + idOut[0]);
|
||||
success = false;
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
logServiceException(e);
|
||||
success = false;
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancels a previously shown Live lock screen.
|
||||
* @param id An identifier for this notification unique within your application.
|
||||
*/
|
||||
public void cancel(int id) {
|
||||
String pkg = mContext.getPackageName();
|
||||
try {
|
||||
sService.cancelLiveLockScreen(pkg, id, UserHandle.myUserId());
|
||||
} catch (RemoteException e) {
|
||||
logServiceException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the default Live lock screen to display when no other Live lock screens are queued
|
||||
* up for display.
|
||||
* <p>
|
||||
* This is not available to third party applications.
|
||||
* </p>
|
||||
*/
|
||||
public void setDefaultLiveLockScreen(@Nullable LiveLockScreenInfo llsInfo) {
|
||||
try {
|
||||
sService.setDefaultLiveLockScreen(llsInfo);
|
||||
} catch (RemoteException e) {
|
||||
logServiceException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the default Live lock screen that is displayed when no other Live lock screens are
|
||||
* queued up for display.
|
||||
* <p>
|
||||
* This is not available to third party applications.
|
||||
* </p>
|
||||
*/
|
||||
public LiveLockScreenInfo getDefaultLiveLockScreen() {
|
||||
try {
|
||||
return sService.getDefaultLiveLockScreen();
|
||||
} catch (RemoteException e) {
|
||||
logServiceException(e);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public LiveLockScreenInfo getCurrentLiveLockScreen() {
|
||||
LiveLockScreenInfo lls = null;
|
||||
try {
|
||||
lls = sService.getCurrentLiveLockScreen();
|
||||
} catch (RemoteException e) {
|
||||
logServiceException(e);
|
||||
}
|
||||
|
||||
return lls;
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public boolean getLiveLockScreenEnabled() {
|
||||
try {
|
||||
return sService.getLiveLockScreenEnabled();
|
||||
} catch (RemoteException e) {
|
||||
logServiceException(e);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public void setLiveLockScreenEnabled(boolean enabled) {
|
||||
try {
|
||||
sService.setLiveLockScreenEnabled(enabled);
|
||||
} catch (RemoteException e) {
|
||||
logServiceException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,262 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The CyanogenMod 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 lineageos.app;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* The PartnerInterface allows applications to interact with a subset of system settings.
|
||||
* </p>
|
||||
*/
|
||||
public class PartnerInterface {
|
||||
/**
|
||||
* Turn off zen mode. This restores the original ring and interruption
|
||||
* settings that the user had set before zen mode was enabled.
|
||||
*
|
||||
* @see #setZenMode
|
||||
*/
|
||||
public static final int ZEN_MODE_OFF = 0;
|
||||
/**
|
||||
* Sets zen mode to important interruptions mode, so that
|
||||
* only notifications that the user has chosen in Settings
|
||||
* to be of high importance will cause the user's device to notify them.
|
||||
*
|
||||
* This condition is held indefinitely until changed again.
|
||||
*
|
||||
* @see #setZenMode and #setZenModeWithDuration
|
||||
*/
|
||||
public static final int ZEN_MODE_IMPORTANT_INTERRUPTIONS = 1;
|
||||
/**
|
||||
* Sets zen mode so that no interruptions will be allowed. The device is
|
||||
* effectively silenced indefinitely, until the mode is changed again.
|
||||
*
|
||||
* @see #setZenMode and #setZenModeWithDuration
|
||||
*/
|
||||
public static final int ZEN_MODE_NO_INTERRUPTIONS = 2;
|
||||
|
||||
|
||||
private static IPartnerInterface sService;
|
||||
|
||||
private Context mContext;
|
||||
|
||||
/**
|
||||
* Allows an application to change network settings,
|
||||
* such as enabling or disabling airplane mode.
|
||||
*/
|
||||
public static final String MODIFY_NETWORK_SETTINGS_PERMISSION =
|
||||
"lineageos.permission.MODIFY_NETWORK_SETTINGS";
|
||||
|
||||
/**
|
||||
* Allows an application to change system sound settings, such as the zen mode.
|
||||
*/
|
||||
public static final String MODIFY_SOUND_SETTINGS_PERMISSION =
|
||||
"lineageos.permission.MODIFY_SOUND_SETTINGS";
|
||||
|
||||
private static final String TAG = "PartnerInterface";
|
||||
|
||||
private static PartnerInterface sPartnerInterfaceInstance;
|
||||
|
||||
private PartnerInterface(Context context) {
|
||||
Context appContext = context.getApplicationContext();
|
||||
if (appContext != null) {
|
||||
mContext = appContext;
|
||||
} else {
|
||||
mContext = context;
|
||||
}
|
||||
sService = getService();
|
||||
if (context.getPackageManager().hasSystemFeature(
|
||||
LineageContextConstants.Features.PARTNER) && sService == null) {
|
||||
throw new RuntimeException("Unable to get PartnerInterfaceService. The service" +
|
||||
" either crashed, was not started, or the interface has been called to early" +
|
||||
" in SystemServer init");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get or create an instance of the {@link lineageos.app.PartnerInterface}
|
||||
* @param context
|
||||
* @return {@link PartnerInterface}
|
||||
*/
|
||||
public static PartnerInterface getInstance(Context context) {
|
||||
if (sPartnerInterfaceInstance == null) {
|
||||
sPartnerInterfaceInstance = new PartnerInterface(context);
|
||||
}
|
||||
return sPartnerInterfaceInstance;
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
static public IPartnerInterface getService() {
|
||||
if (sService != null) {
|
||||
return sService;
|
||||
}
|
||||
IBinder b = ServiceManager.getService(LineageContextConstants.LINEAGE_PARTNER_INTERFACE);
|
||||
if (b != null) {
|
||||
sService = IPartnerInterface.Stub.asInterface(b);
|
||||
return sService;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns on or off airplane mode.
|
||||
*
|
||||
* You will need {@link #MODIFY_NETWORK_SETTINGS_PERMISSION}
|
||||
* to utilize this functionality.
|
||||
* @param enabled if true, sets airplane mode to enabled, otherwise disables airplane mode.
|
||||
*/
|
||||
public void setAirplaneModeEnabled(boolean enabled) {
|
||||
if (sService == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
sService.setAirplaneModeEnabled(enabled);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, e.getLocalizedMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns on or off mobile network.
|
||||
*
|
||||
* You will need {@link #MODIFY_NETWORK_SETTINGS_PERMISSION}
|
||||
* to utilize this functionality.
|
||||
* @param enabled if true, sets mobile network to enabled, otherwise disables mobile network.
|
||||
*/
|
||||
public void setMobileDataEnabled(boolean enabled) {
|
||||
if (sService == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
sService.setMobileDataEnabled(enabled);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, e.getLocalizedMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the zen mode for the device.
|
||||
*
|
||||
* You will need {@link #MODIFY_SOUND_SETTINGS_PERMISSION}
|
||||
* to utilize this functionality.
|
||||
*
|
||||
* @see #ZEN_MODE_IMPORTANT_INTERRUPTIONS
|
||||
* @see #ZEN_MODE_NO_INTERRUPTIONS
|
||||
* @see #ZEN_MODE_OFF
|
||||
* @param mode The zen mode to set the device to.
|
||||
* One of {@link #ZEN_MODE_IMPORTANT_INTERRUPTIONS},
|
||||
* {@link #ZEN_MODE_NO_INTERRUPTIONS} or
|
||||
* {@link #ZEN_MODE_OFF}.
|
||||
*/
|
||||
public boolean setZenMode(int mode) {
|
||||
if (sService == null) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
return sService.setZenMode(mode);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, e.getLocalizedMessage(), e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the zen mode for the device, allow a duration parameter
|
||||
*
|
||||
* You will need {@link #MODIFY_SOUND_SETTINGS_PERMISSION}
|
||||
* to utilize this functionality.
|
||||
*
|
||||
* @see #ZEN_MODE_IMPORTANT_INTERRUPTIONS
|
||||
* @see #ZEN_MODE_NO_INTERRUPTIONS
|
||||
* @param mode The zen mode to set the device to.
|
||||
* One of {@link #ZEN_MODE_IMPORTANT_INTERRUPTIONS},
|
||||
* {@link #ZEN_MODE_NO_INTERRUPTIONS}.
|
||||
* If using {@link #ZEN_MODE_OFF}, the duration will be ignored
|
||||
* @param durationMillis The duration in milliseconds,
|
||||
* if duration + System.currentTimeMillis() results in
|
||||
* long overflow, duration will be "indefinitely".
|
||||
* all durationMillis < 0 will mean "indefinitely".
|
||||
*
|
||||
*/
|
||||
public boolean setZenModeWithDuration(int mode, long durationMillis) {
|
||||
if (sService == null) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
return sService.setZenModeWithDuration(mode, durationMillis);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, e.getLocalizedMessage(), e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shuts down the device, immediately.
|
||||
*
|
||||
* You will need {@link android.Manifest.permission.REBOOT}
|
||||
* to utilize this functionality.
|
||||
*/
|
||||
public void shutdownDevice() {
|
||||
if (sService == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
sService.shutdown();
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, e.getLocalizedMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reboots the device, immediately.
|
||||
*
|
||||
* You will need {@link android.Manifest.permission.REBOOT}
|
||||
* to utilize this functionality.
|
||||
*/
|
||||
public void rebootDevice() {
|
||||
if (sService == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
sService.reboot();
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, e.getLocalizedMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the package name of the application that currently holds the
|
||||
* {@link lineageos.media.MediaRecorder.AudioSource#HOTWORD} input.
|
||||
* @return The package name or null if no application currently holds the HOTWORD input.
|
||||
*/
|
||||
public String getCurrentHotwordPackageName() {
|
||||
if (sService == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return sService.getCurrentHotwordPackageName();
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, e.getLocalizedMessage(), e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -95,13 +95,6 @@ public class Intent {
|
||||
*/
|
||||
public static final String ACTION_APP_FAILURE = "lineageos.intent.action.APP_FAILURE";
|
||||
|
||||
/**
|
||||
* Implicit action to open live lock screen settings.
|
||||
* @hide
|
||||
*/
|
||||
public static final String ACTION_OPEN_LIVE_LOCKSCREEN_SETTINGS =
|
||||
"lineageos.intent.action.OPEN_LIVE_LOCKSCREEN_SETTINGS";
|
||||
|
||||
/**
|
||||
* Broadcast action: lid state changed
|
||||
* @hide
|
||||
|
||||
@@ -99,7 +99,6 @@ public class Build {
|
||||
* <li>Hardware Abstraction Framework Access via
|
||||
* {@link lineageos.hardware.LineageHardwareManager} (Not for use by 3rd parties)
|
||||
* <li>MSIM API via {@link lineageos.app.LineageTelephonyManager}
|
||||
* <li>Interface for partners via {@link lineageos.app.PartnerInterface}
|
||||
* <li>Introductory Settings Provider {@link lineageos.providers.LineageSettings}
|
||||
* <li>AlarmClock API via {@link lineageos.alarmclock.LineageOSAlarmClock}
|
||||
* </ul>
|
||||
|
||||
@@ -2829,20 +2829,6 @@ public final class LineageSettings {
|
||||
*/
|
||||
public static final String PROTECTED_COMPONENT_MANAGERS = "protected_component_managers";
|
||||
|
||||
/**
|
||||
* Whether live lock screen is currently enabled/disabled by the user.
|
||||
* Boolean settings. 0 = off, 1 = on
|
||||
* @hide
|
||||
*/
|
||||
public static final String LIVE_LOCK_SCREEN_ENABLED = "live_lock_screen_enabled";
|
||||
|
||||
/**
|
||||
* The user selected Live lock screen to display
|
||||
* @hide
|
||||
*/
|
||||
public static final String DEFAULT_LIVE_LOCK_SCREEN_COMPONENT =
|
||||
"default_live_lock_screen_component";
|
||||
|
||||
/**
|
||||
* Whether keyguard will direct show security view (0 = false, 1 = true)
|
||||
* @hide
|
||||
@@ -2868,12 +2854,6 @@ public final class LineageSettings {
|
||||
*/
|
||||
public static final String DISPLAY_GAMMA_CALIBRATION_PREFIX = "display_gamma_";
|
||||
|
||||
/**
|
||||
* Enabled live lockscreen components. Delimited by "|"
|
||||
* @hide
|
||||
*/
|
||||
public static final String ENABLED_EVENT_LIVE_LOCKS_KEY = "live_lockscreens_events_enabled";
|
||||
|
||||
/**
|
||||
* Current active & enabled Weather Provider Service
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user