Skip to content

Commit

Permalink
pocket: introduce pocket judge
Browse files Browse the repository at this point in the history
    * Judge if device is in pocket.
    * Notify clients callbacks when pocked state changes.
    * Start listening when device becomes not interactive.
    * Stop listening when device becomes interactive and is NOT in pocket.
    * Addresses NOUGAT-9.

Signed-off-by: klozz <[email protected]>
  • Loading branch information
kaluoshi authored and Klozz committed Apr 14, 2017
1 parent 736db8b commit 424bcfe
Show file tree
Hide file tree
Showing 12 changed files with 1,015 additions and 2 deletions.
2 changes: 2 additions & 0 deletions Android.mk
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,8 @@ LOCAL_SRC_FILES += \
core/java/android/os/IUpdateLock.aidl \
core/java/android/os/IUserManager.aidl \
core/java/android/os/IVibratorService.aidl \
core/java/android/pocket/IPocketService.aidl \
core/java/android/pocket/IPocketCallback.aidl \
core/java/android/security/IKeystoreService.aidl \
core/java/android/service/carrier/ICarrierService.aidl \
core/java/android/service/carrier/ICarrierMessagingCallback.aidl \
Expand Down
1 change: 1 addition & 0 deletions CleanSpec.mk
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ $(call add-clean-step, rm -rf $(PRODUCT_OUT)/symbols/system/lib/libhwui.so)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib/libhwui.so)
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/os/storage/*)
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/content/IClipboard.P)
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/pocket/*)
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/telephony/java/com/android/internal/telephony/ITelephonyRegistry.P)
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/android_stubs_current_intermediates)
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/docs/api-stubs*)
Expand Down
11 changes: 11 additions & 0 deletions core/java/android/app/SystemServiceRegistry.java
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@
import android.os.Vibrator;
import android.os.health.SystemHealthManager;
import android.os.storage.StorageManager;
import android.pocket.IPocketService;
import android.pocket.PocketManager;
import android.print.IPrintManager;
import android.print.PrintManager;
import android.hardware.fingerprint.FingerprintManager;
Expand Down Expand Up @@ -644,6 +646,15 @@ public FingerprintManager createService(ContextImpl ctx) {
return new FingerprintManager(ctx.getOuterContext(), service);
}});

registerService(Context.POCKET_SERVICE, PocketManager.class,
new CachedServiceFetcher<PocketManager>() {
@Override
public PocketManager createService(ContextImpl ctx) {
IBinder binder = ServiceManager.getService(Context.POCKET_SERVICE);
IPocketService service = IPocketService.Stub.asInterface(binder);
return new PocketManager(ctx.getOuterContext(), service);
}});

registerService(Context.TV_INPUT_SERVICE, TvInputManager.class,
new StaticServiceFetcher<TvInputManager>() {
@Override
Expand Down
10 changes: 10 additions & 0 deletions core/java/android/content/Context.java
Original file line number Diff line number Diff line change
Expand Up @@ -3662,6 +3662,16 @@ public final <T> T getSystemService(Class<T> serviceClass) {
*/
public static final String OVERLAY_SERVICE = "overlay";

/**
* Use with {@link #getSystemService} to retrieve a
* {@link android.os.PocketManager} for accessing and listening to device pocket state.
*
* @hide
* @see #getSystemService
* @see android.os.PocketManager
*/
public static final String POCKET_SERVICE = "pocket";

/**
* Determine whether the given permission is allowed for a particular
* process and user ID running in the system.
Expand Down
24 changes: 24 additions & 0 deletions core/java/android/pocket/IPocketCallback.aidl
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/**
* Copyright (C) 2016 The ParanoidAndroid 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 android.pocket;

/** @hide */
interface IPocketCallback {

// notify when pocket state changes.
void onStateChanged(boolean isDeviceInPocket, int reason);

}
39 changes: 39 additions & 0 deletions core/java/android/pocket/IPocketService.aidl
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/**
* Copyright (C) 2016 The ParanoidAndroid 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 android.pocket;

import android.pocket.IPocketCallback;

/** @hide */
interface IPocketService {

// add callback to get notified about pocket state.
void addCallback(IPocketCallback callback);

// remove callback and stop getting notified about pocket state.
void removeCallback(IPocketCallback callback);

// notify pocket service about intercative state changed.
// @see com.android.policy.PhoneWindowManager
void onInteractiveChanged(boolean interactive);

// external processes can request changing listening state.
void setListeningExternal(boolean listen);

// check if device is in pocket.
boolean isDeviceInPocket();

}
25 changes: 25 additions & 0 deletions core/java/android/pocket/PocketConstants.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package android.pocket;

/**
* This class contains global pocket setup constants.
* @author Carlo Savignano
* @hide
*/

public class PocketConstants {

public static final boolean DEBUG = false;
public static final boolean DEBUG_SPEW = false;

/**
* Whether to use proximity sensor to evaluate pocket state.
*/
public static final boolean ENABLE_PROXIMITY_JUDGE = true;

/**
* Whether to use light sensor to evaluate pocket state.
*/
public static final boolean ENABLE_LIGHT_JUDGE = true;


}
168 changes: 168 additions & 0 deletions core/java/android/pocket/PocketManager.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
/**
* Copyright (C) 2016 The ParanoidAndroid 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 android.pocket;

import android.content.Context;
import android.os.RemoteException;
import android.util.Log;
import android.util.Slog;

/**
* A class that coordinates listening for pocket state.
* <p>
* Use {@link android.content.Context#getSystemService(java.lang.String)}
* with argument {@link android.content.Context#POCKET_SERVICE} to get
* an instance of this class.
*
* Usage: import and create a final {@link IPocketCallback.Stub()} and implement your logic in
* {@link IPocketCallback#onStateChanged(boolean, int)}. Then add your callback to the pocket manager
*
* // define a final callback
* private final IPocketCallback mCallback = new IPocketCallback.Stub() {
*
* @Override
* public void onStateChanged(boolean isDeviceInPocket, int reason) {
* // Your method to handle logic outside of this callback, ideally with a handler
* // posting on UI Thread for view hierarchy operations or with its own background thread.
* handlePocketStateChanged(isDeviceInPocket, reason);
* }
*
* }
*
* // add callback to pocket manager
* private void addCallback() {
* PocketManager manager = (PocketManager) context.getSystemService(Context.POCKET_SERVICE);
* manager.addCallback(mCallback);
* }
*
* @author Carlo Savignano
* @hide
*/
public class PocketManager {

private static final String TAG = PocketManager.class.getSimpleName();

/**
* Whether {@link IPocketCallback#onStateChanged(boolean, int)}
* was fired because of the sensor.
* @see PocketService#handleDispatchCallbacks()
*/
public static final int REASON_SENSOR = 0;

/**
* Whether {@link IPocketCallback#onStateChanged(boolean, int)}
* was fired because of an error while accessing service.
* @see #addCallback(IPocketCallback)
* @see #removeCallback(IPocketCallback)
*/
public static final int REASON_ERROR = 1;

/**
* Whether {@link IPocketCallback#onStateChanged(boolean, int)}
* was fired because of a needed reset.
* @see PocketService#binderDied()
*/
public static final int REASON_RESET = 2;

private Context mContext;
private IPocketService mService;

public PocketManager(Context context, IPocketService service) {
mContext = context;
mService = service;
if (mService == null) {
Slog.v(TAG, "PocketService was null");
}
}

/**
* Add pocket state callback.
* @see PocketService#handleRemoveCallback(IPocketCallback)
*/
public void addCallback(final IPocketCallback callback) {
if (mService != null) try {
mService.addCallback(callback);
} catch (RemoteException e1) {
Log.w(TAG, "Remote exception in addCallback: ", e1);
if (callback != null){
try {
callback.onStateChanged(false, REASON_ERROR);
} catch (RemoteException e2) {
Log.w(TAG, "Remote exception in callback.onPocketStateChanged: ", e2);
}
}
}
}

/**
* Remove pocket state callback.
* @see PocketService#handleAddCallback(IPocketCallback)
*/
public void removeCallback(final IPocketCallback callback) {
if (mService != null) try {
mService.removeCallback(callback);
} catch (RemoteException e1) {
Log.w(TAG, "Remote exception in removeCallback: ", e1);
if (callback != null){
try {
callback.onStateChanged(false, REASON_ERROR);
} catch (RemoteException e2) {
Log.w(TAG, "Remote exception in callback.onPocketStateChanged: ", e2);
}
}
}
}

/**
* Notify service about device interactive state changed.
* {@link PhoneWindowManager#startedWakingUp()}
* {@link PhoneWindowManager#startedGoingToSleep(int)}
*/
public void onInteractiveChanged(boolean interactive) {
if (mService != null) try {
mService.onInteractiveChanged(interactive);
} catch (RemoteException e) {
Log.w(TAG, "Remote exception in addCallback: ", e);
}
}

/**
* Request listening state change by, but not limited to, external process.
* @see PocketService#handleSetListeningExternal(boolean)
*/
public void setListeningExternal(boolean listen) {
if (mService != null) try {
mService.setListeningExternal(listen);
} catch (RemoteException e) {
Log.w(TAG, "Remote exception in setListeningExternal: ", e);
}
}

/**
* Return whether device is in pocket.
* @see PocketService#isDeviceInPocket()
* @return
*/
public boolean isDeviceInPocket() {
if (mService != null) try {
return mService.isDeviceInPocket();
} catch (RemoteException e) {
Log.w(TAG, "Remote exception in isDeviceInPocket: ", e);
}
return false;
}

}
15 changes: 13 additions & 2 deletions core/java/android/provider/Settings.java
Original file line number Diff line number Diff line change
Expand Up @@ -3780,7 +3780,7 @@ public boolean validate(String value) {
* @hide
*/
public static final String LOCKSCREEN_CHARGING_CURRENT = "lockscreen_charging_current";

/**
* Fling pulse lavalamp psychedelic colors
*
Expand Down Expand Up @@ -3843,7 +3843,7 @@ public boolean validate(String value) {
* @hide
*/
public static final String PULSE_LAVALAMP_SOLID_SPEED = "lava_lamp_solid_speed";

/**
* Immersive recents options
*
Expand Down Expand Up @@ -3942,6 +3942,15 @@ public boolean validate(String value) {
*/
public static final String AMBIENT_DISPLAY_SHOW_BATTERY = "ambient_display_show_battery";

/**
* Whether allowing pocket service to register sensors and dispatch informations.
* 0 = disabled
* 1 = enabled
* @author Carlo Savignano
* @hide
*/
public static final String POCKET_JUDGE = "pocket_judge";

/**
* Settings to backup. This is here so that it's in the same place as the settings
* keys and easy to update.
Expand Down Expand Up @@ -4147,6 +4156,8 @@ public boolean validate(String value) {
PRIVATE_SETTINGS.add(POINTER_SPEED);
PRIVATE_SETTINGS.add(LOCK_TO_APP_ENABLED);
PRIVATE_SETTINGS.add(EGG_MODE);
// Pocket mode handler.
PRIVATE_SETTINGS.add(POCKET_JUDGE);
}

/**
Expand Down
Loading

0 comments on commit 424bcfe

Please sign in to comment.