aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/java/cyanogenmod/app/BaseLiveLockManagerService.java226
-rw-r--r--src/java/cyanogenmod/app/CMContextConstants.java13
-rw-r--r--src/java/cyanogenmod/app/ILiveLockScreenChangeListener.aidl27
-rw-r--r--src/java/cyanogenmod/app/ILiveLockScreenManager.aidl73
-rw-r--r--src/java/cyanogenmod/app/ILiveLockScreenManagerProvider.aidl65
-rw-r--r--src/java/cyanogenmod/app/LiveLockScreenInfo.aidl19
-rw-r--r--src/java/cyanogenmod/app/LiveLockScreenInfo.java196
-rw-r--r--src/java/cyanogenmod/app/LiveLockScreenManager.java182
-rw-r--r--src/java/cyanogenmod/providers/CMSettings.java7
9 files changed, 808 insertions, 0 deletions
diff --git a/src/java/cyanogenmod/app/BaseLiveLockManagerService.java b/src/java/cyanogenmod/app/BaseLiveLockManagerService.java
new file mode 100644
index 0000000..feae94f
--- /dev/null
+++ b/src/java/cyanogenmod/app/BaseLiveLockManagerService.java
@@ -0,0 +1,226 @@
+/*
+ * 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 cyanogenmod.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 cyanogenmod.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 cyanogenmod.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 cyanogenmod.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 cyanogenmod.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 cyanogenmod.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);
+ }
+ };
+}
diff --git a/src/java/cyanogenmod/app/CMContextConstants.java b/src/java/cyanogenmod/app/CMContextConstants.java
index e90d8ed..6b2cb23 100644
--- a/src/java/cyanogenmod/app/CMContextConstants.java
+++ b/src/java/cyanogenmod/app/CMContextConstants.java
@@ -115,6 +115,11 @@ public final class CMContextConstants {
public static final String CM_ICON_CACHE_SERVICE = "cmiconcache";
/**
+ * @hide
+ */
+ public static final String CM_LIVE_LOCK_SCREEN_SERVICE = "cmlivelockscreen";
+
+ /**
* Features supported by the CMSDK.
*/
public static class Features {
@@ -181,5 +186,13 @@ public final class CMContextConstants {
*/
@SdkConstant(SdkConstant.SdkConstantType.FEATURE)
public static final String PARTNER = "org.cyanogenmod.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.cyanogenmod.livelockscreen";
}
}
diff --git a/src/java/cyanogenmod/app/ILiveLockScreenChangeListener.aidl b/src/java/cyanogenmod/app/ILiveLockScreenChangeListener.aidl
new file mode 100644
index 0000000..48e7f36
--- /dev/null
+++ b/src/java/cyanogenmod/app/ILiveLockScreenChangeListener.aidl
@@ -0,0 +1,27 @@
+/*
+** 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 cyanogenmod.app;
+
+import cyanogenmod.app.LiveLockScreenInfo;
+
+/**
+ * Listener interface for notifying clients that the current Live lock screen has changed.
+ * @hide
+ */
+interface ILiveLockScreenChangeListener {
+ void onLiveLockScreenChanged(in LiveLockScreenInfo llsInfo);
+} \ No newline at end of file
diff --git a/src/java/cyanogenmod/app/ILiveLockScreenManager.aidl b/src/java/cyanogenmod/app/ILiveLockScreenManager.aidl
new file mode 100644
index 0000000..15142c1
--- /dev/null
+++ b/src/java/cyanogenmod/app/ILiveLockScreenManager.aidl
@@ -0,0 +1,73 @@
+/*
+** 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 cyanogenmod.app;
+
+import cyanogenmod.app.ILiveLockScreenChangeListener;
+import cyanogenmod.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);
+} \ No newline at end of file
diff --git a/src/java/cyanogenmod/app/ILiveLockScreenManagerProvider.aidl b/src/java/cyanogenmod/app/ILiveLockScreenManagerProvider.aidl
new file mode 100644
index 0000000..933eb97
--- /dev/null
+++ b/src/java/cyanogenmod/app/ILiveLockScreenManagerProvider.aidl
@@ -0,0 +1,65 @@
+/*
+** 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 cyanogenmod.app;
+
+import cyanogenmod.app.ILiveLockScreenChangeListener;
+import cyanogenmod.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);
+} \ No newline at end of file
diff --git a/src/java/cyanogenmod/app/LiveLockScreenInfo.aidl b/src/java/cyanogenmod/app/LiveLockScreenInfo.aidl
new file mode 100644
index 0000000..bffa3b0
--- /dev/null
+++ b/src/java/cyanogenmod/app/LiveLockScreenInfo.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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 cyanogenmod.app;
+
+parcelable LiveLockScreenInfo;
diff --git a/src/java/cyanogenmod/app/LiveLockScreenInfo.java b/src/java/cyanogenmod/app/LiveLockScreenInfo.java
new file mode 100644
index 0000000..33afd89
--- /dev/null
+++ b/src/java/cyanogenmod/app/LiveLockScreenInfo.java
@@ -0,0 +1,196 @@
+/*
+ * 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 cyanogenmod.app;
+
+import android.annotation.NonNull;
+import android.content.ComponentName;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import android.text.TextUtils;
+import cyanogenmod.os.Build;
+
+/**
+ * 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 cyanogenmod.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, make sure to define explicit changes
+ // within {@link Build.PARCELABLE_VERSION);
+ int version = source.readInt();
+ int size = source.readInt();
+ int start = source.dataPosition();
+
+ this.priority = source.readInt();
+ String component = source.readString();
+ this.component = !TextUtils.isEmpty(component)
+ ? ComponentName.unflattenFromString(component)
+ : null;
+
+ source.setDataPosition(start + size);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ // Write parcelable version, make sure to define explicit changes
+ // within {@link Build.PARCELABLE_VERSION);
+ dest.writeInt(Build.PARCELABLE_VERSION);
+ int sizePos = dest.dataPosition();
+ // Inject a placeholder that will store the parcel size from this point on
+ // (not including the size itself).
+ dest.writeInt(0);
+ int dataStartPos = dest.dataPosition();
+
+ dest.writeInt(priority);
+ dest.writeString(component != null ? component.flattenToString() : "");
+
+ // Go back and write size
+ int size = dest.dataPosition() - dataStartPos;
+ dest.setDataPosition(sizePos);
+ dest.writeInt(size);
+ dest.setDataPosition(dataStartPos + size);
+ }
+
+ @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);
+ }
+ }
+}
diff --git a/src/java/cyanogenmod/app/LiveLockScreenManager.java b/src/java/cyanogenmod/app/LiveLockScreenManager.java
new file mode 100644
index 0000000..c5fa4ce
--- /dev/null
+++ b/src/java/cyanogenmod/app/LiveLockScreenManager.java
@@ -0,0 +1,182 @@
+/*
+ * 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 cyanogenmod.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
+ = "cyanogenmod.app.LiveLockScreenManagerService";
+
+ private LiveLockScreenManager(Context context) {
+ mContext = context;
+ sService = getService();
+ if (context.getPackageManager().hasSystemFeature(
+ CMContextConstants.Features.LIVE_LOCK_SCREEN) && sService == null) {
+ throw new RuntimeException("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(CMContextConstants.CM_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);
+ }
+ }
+}
diff --git a/src/java/cyanogenmod/providers/CMSettings.java b/src/java/cyanogenmod/providers/CMSettings.java
index 9859415..8d76bb0 100644
--- a/src/java/cyanogenmod/providers/CMSettings.java
+++ b/src/java/cyanogenmod/providers/CMSettings.java
@@ -2649,6 +2649,13 @@ public final class CMSettings {
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
*/